読者です 読者をやめる 読者になる 読者になる

はまったりひらめいたり…とか…

.Net系プログラムで勉強したこととか嵌ったことについて書いたりします。

jQueyプラグインをAngular v2で使いたい(FullCalendar)

Angularを使用するようになって、jQuery自体は殆ど使用しなくなりました。

Componentベースでアプリを作成したときに

jQueryの処理が全体に波及するので使いにくかったんですね。

(特に同じ部品のComonentを親Componentで何度も使用しているときとか。)

ただ。jQueryの覇権時代が長いだけに

色々と使えるjQueryプラグインが存在するわけで

それを使いたいなー。という思いもあるわけです。

なので、今回は、jQueryプラグインをAngularで使用してみたいと思います。

How to include JQuery plugins in Angular 2 running via webpack

といっても、上記の記事の焼き直しみたいな感じになっていますが…

今回は手っ取り早くangular-cliを使用して、作ってみようと思います。

angular-cliを使用することで

比較的手軽にangularの開発&Build環境を構築することが可能です。

angular-cliの使い方は今回の本筋ではないので下記を参考に。

www.npmjs.com

developers.eure.jp

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を使用している場合

外部コンポーネント等のCSSJavascriptを使用しやすいです。

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の機能の諸々を使用しやすいようにしています。

動作させてみる

f:id:TakasDev:20170306212222g:plain

Console内部にイベントオブジェクトを表記するようにしています。

moment型のデータ等が問題なく取得できていることが確認できるかと思います。

最後に

一応今回のソースは下記に上げてあります。

Angular2Study/UseFullCalender at master · Takas0522/Angular2Study · GitHub