jQueyプラグインをAngular v2で使いたい(FullCalendar)
Angularを使用するようになって、jQuery自体は殆ど使用しなくなりました。
Componentベースでアプリを作成したときに
jQueryの処理が全体に波及するので使いにくかったんですね。
(特に同じ部品のComonentを親Componentで何度も使用しているときとか。)
ただ。jQueryの覇権時代が長いだけに
それを使いたいなー。という思いもあるわけです。
なので、今回は、jQueryのプラグインをAngularで使用してみたいと思います。
How to include JQuery plugins in Angular 2 running via webpack
といっても、上記の記事の焼き直しみたいな感じになっていますが…
今回は手っ取り早くangular-cliを使用して、作ってみようと思います。
angular-cliを使用することで
比較的手軽にangularの開発&Build環境を構築することが可能です。
angular-cliの使い方は今回の本筋ではないので下記を参考に。
npmでパッケージをダウンロード
まずは、モノがないと始まらないので
jQueryと今回使用したいFullCalendarをnpmでダウンロードします。
npm install jquery npm install fullcalendar
型定義ファイル+αをダウンロード
jQueryとFullCalendarは型定義ファイルが提供されているので
下記の2つの型定義ファイルをダウンロードします。
npm install @types/jquery npm install @types/fullcalendar
また、FullCalendarの型定義ファイル上で
日付等の指定にmoment.jsの型が指定されているので
moment.jsと、その型定義ファイル @types/momentもダウンロードします。
npm install moment npm install @types/moment
angular-cli.json
Angular-cliを使用している場合
外部コンポーネント等のCSSやJavascriptを使用しやすいです。
angular-cli.jsonに外部JSやCSSを読み込むオプションが存在するためです。
今回、FullCalendarを使用するため、FullCalendarのCSSを別に読み込みます。
"styles": [ "../node_modules/fullcalendar/dist/fullcalendar.css" ]
FullCalendarの実装
参考サイトの通り、FullCalendarを使用するComponentを分離して作成します。
Htmlにng-contentを指定し、そこにjQueryでFullCalendarを注入します。
HTML
<ng-content></ng-content>
Component上のHTMLにはng-contentしかないので
this.elementRef.nativeElementのみで指定できますね。
型定義ファイルを使用することで型検証されるようになるため
どのような値をつっこめば良いのかわかりやすくなります。ビバ型。
TypeScript
this.calendarElement = jQuery(this.elementRef.nativeElement); this.calendarElement.fullCalendar({ editable: true, defaultView: 'agendaWeek', selectable: true, selectHelper: true });
仕上げ
あとは上記で作成したComponentを使用し、[ng serve]で実行して動作確認です。
表示するだけでは味気ないので、下のように書き換えてみました。
this.calendarElement = jQuery(this.elementRef.nativeElement); this.calendarElement.fullCalendar({ allDayText: '終日', editable: true, defaultView: 'agendaWeek', selectable: true, selectHelper: true, slotDuration: moment.duration(15, 'minutes'), slotLabelFormat : 'H:mm', buttonText: { today: '今日' }, monthNames: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'], dayNames: ['日曜日', '月曜日', '火曜日', '水曜日', '木曜日', '金曜日', '土曜日'], dayNamesShort: ['日', '月', '火', '水', '木', '金', '土'], views: { month: { columnFormat: 'ddd' }, week: { columnFormat: 'D[(]ddd[)]' }, day: { columnFormat: 'D[(]ddd[)]' } }, select: this.onSelectFunction, eventDragStop: this.onDropFunction, eventResize: this.onReSizeFunction, eventRender: this.addEventRender });
/*FullCalendarで定義されていないイベントを付与する(ダブルクリック)*/ private addEventRender = function(event: FC.EventObject, element: any){ element.bind('dblclick', () => { alert('onDoubleClickEbent'); console.log(event); }); } /*カレンダーセレクト時*/ private onSelectFunction = function(start, end){ let eventTitle = prompt('予定の名称を入力せよ!!'); let eventData: FC.EventObject = { start: start, end: end, title: eventTitle }; this.calendarElement.fullCalendar('renderEvent', eventData, true); this.calendarElement.fullCalendar('unselect'); }.bind(this); /*イベントオブジェクト移動時*/ private onDropFunction = function(event: FC.EventObject){ console.log('Drop!'); console.log(event); }.bind(this); /*イベントオブジェクトサイズ変更時*/ private onReSizeFunction = function(event: FC.EventObject){ console.log('ReSize!'); console.log(event); }.bind(this);
日付の表示Formatを変更し、各イベントの処理を実装します。
イベントの引数はFunctionを指定しますが
その場合、calendarElementのobjectが[this]となります。
Angularを使用するうえで色々と使いづらいので、Functionにthisをbindして
FullCalendarを宣言しているClassのオブジェクトを[this]としています。
そうすることで、Angularの機能の諸々を使用しやすいようにしています。
動作させてみる
Console内部にイベントオブジェクトを表記するようにしています。
moment型のデータ等が問題なく取得できていることが確認できるかと思います。
最後に
一応今回のソースは下記に上げてあります。
Angular2Study/UseFullCalender at master · Takas0522/Angular2Study · GitHub