目標
因為目標是可以選擇日期區間(date range),還要可以選擇時間(time)的,所以找了 daterangepicker 這個套件,是可以做到想要的效果,但不知道怎麼在 Angular 中使用。教學只有 JavaScript 的寫法,很令人崩潰。所以首先要來研究如何在 Angular 中使用 daterangepicker 套件。


先說結論
需要用 npm 安裝 jquery、moment、daterangepicker,然後在 angular.json 中加入 daterangepicker.css 的路徑(也可以順便加上 jquery.min.js、moment.min.js、daterangepicker.js 的路徑),再到需要用到的 component 的 ts 檔 import 即可。

研究過程
整個嘗試的過程有點存在著實驗精神,其實只要看「研究 4」就好了。
- 研究 1:把全部程式碼放在 index.html 看看(可以)
- 研究 2:把 html 放在 app.component.html 看看(不行)
- 研究 3:把 JavaScript 程式碼放在 app.component.ts 裡看看(不行)
- 研究 4:npm install,再 import(可以)
- 研究 5:angular.json 檔是否可以取代 import(不行)
- 研究 6:import 在 app.component.ts 的話,其他 component 是否可以使用(不行)
- 研究 7:import 在 app.module.ts 的話,其他 component 是否可以使用(不行)
研究 1:把全部程式碼放在 index.html 看看(可以)

官網文件寫的 JavaScript 版本很簡單,就是放 jquery、moment、daterangepicker 的 CDN,然後 html、javascript / jquery。把這些程式碼放在 index.html 看看:

這樣子是可以用的:

研究 2:把 html 放在 app.component.html 看看(不行)


把 CDN 留在 index.html,其他移到 app.component.html。這樣完全不行:

研究 3:把 JavaScript 程式碼放在 app.component.ts 裡看看(不行)



這樣雖然在 run $ ng serve 的 Terminal 報了一堆 error,但是很神奇的竟然在 web 可以用耶(但是後來又不行了):


來試看看 error 第一條,run 指令:
$ npm i @types/jquery --save

然後在 tsconfig.app.json(主要)跟 tsconfig.spec.json 的 types 都加入 jquery:


這樣雖然沒有報 jquery 的 error 了,但還是有報 moment 跟 daterangepicker 的 error:

研究 4:npm install,再 import(可以)
試試看 npm install jquery、moment、daterangepicker:
$ npm i jquery --save

先參考「How To Use jQuery With Angular (When You Absolutely Have To)」這篇文章,先讓 jquery 可以在 Angular 中使用。
- Making jQuery library ‘Global’:在 angular.json 檔中的 scripts 陣列加入 “./node_modules/jquery/dist/jquery.min.js”,然後再重新 $ ng serve。

- 新增一個 picker component:$ ng g c picker
- Using jQuery in Angular application:在 picker.component.html 加入一個很簡單的 button,在 picker.component.ts 加入 $ 相關的程式碼,這樣是可以有 alert 的效果的。


- 但這個做法好像不是很理想。參考「How to Include and Use jQuery in Angular CLI Project」這篇文章,把「declare var $: any;」改成「import * as $ from ‘jquery’;」,發現也是可以。

jquery 看起來是可以了,那再來試試看 moment。
$ npm i moment --save

參考 moment 的官方文件,Typescript 的部分,在 picker.component.ts 加入 moment 有關的程式碼:「import * as moment from ‘moment’;」、「let now = moment().format(‘LLLL’);」

有成功印出現在時間!

所以 moment 也 OK 了,剩下 daterangepicker 的部分。先整理一下 jquery 跟 moment 的用法:
- jquery:npm install 之後(再在 angular.json 檔加入 jquery.min.js 的路徑,重新 ng serve)在 component 的 ts 檔 import 即可。
- moment:npm install 之後,在 component 的 ts 檔 import 即可。
所以,預期 daterangepicker 應該也要差不多這樣才對。
$ npm i daterangepicker --save

$ npm i @types/daterangepicker --save

在 picker.component.html 放一個 <input>:

在 picker.component.ts 加入 daterangepicker 相關的程式碼:「import ‘daterangepicker’;」、「$(‘input[name=”dates”]’).daterangepicker();」

這樣可以 work 耶~只是看起來沒有 css,但功能感覺是有的。

在 angular.json 中的 styles 加入 daterangepicker.css 的路徑:「”./node_modules/daterangepicker/daterangepicker.css”」

重新 $ ng serve 之後,就可以了!!!

小結一下,所以 daterangepicker 的用法是:
- daterangepicker:npm install 之後,在 component 的 ts 檔 import,在 angular.json 檔加入 daterangepicker.css 的路徑,重新 ng serve,即可。
也就是說,套件們在 npm install 之後有 1 個或 2 個動作需要做:
- 在 component 的 ts 檔 import
- 在 angular.json 檔加入 css 檔或是 js 檔的路徑
研究 5:angular.json 檔是否可以取代 import(不行)
目前在 angular.json 檔中,只有加入 daterangepicker.css 的路徑,而 daterangepicker 本身是在 component 的 ts 檔中 import 的。
想知道如果把 daterangepicker.js 的路徑一樣加入到 angular.json 檔,那是不是就可以不用 import 了?
由於 daterangepicker 的 CDN 順序是 jquery -> moment -> daterangepicker,先嘗試 jquery 的部分。
在 angular.json 檔中加入 jquery 的路徑「”./node_modules/jquery/dist/jquery.min.js”」,然後在 ts 檔中把 jquery 的 import 拿掉,重新 $ ng serve,完全不能用。
不知道跟 @type/jquery 有沒有關係,但試試看:
$ npm i @types/jquery --save

還是不行,感覺跟 @type/jquery 沒有關係。所以結論是不行,沒有 import 一樣無法使用。
研究 6:import 在 app.component.ts 的話,其他 component 是否可以使用(不行)
把 picker.component.ts 中的「import * as $ from ‘jquery’;」移到 app.component.ts,結果還是不能使用。
研究 7:import 在 app.module.ts 的話,其他 component 是否可以使用(不行)
把 picker.component.ts 中的「import * as $ from ‘jquery’;」移到 app.module.ts,結果還是不能使用。
總結
需要安裝 jquery、moment、daterangepicker,安裝方法簡要如下:
- jquery:npm install 之後(再在 angular.json 檔加入 jquery.min.js 的路徑,重新 ng serve)在 component 的 ts 檔 import 即可。
- moment:npm install 之後,在 component 的 ts 檔 import 即可。
- daterangepicker:npm install 之後,在 component 的 ts 檔 import,在 angular.json 檔加入 daterangepicker.css 的路徑,重新 ng serve,即可。
記得有改到 angular.json 都要重新 ng serve。雖然不是很清楚 js 在 angular.json 裡面的作用是什麼(每次加入了還是一樣要在 ts 中 import 才能用啊),但貌似把有用到的套件都紀錄在 angular.json 裡也是不錯的,可以給自己安裝了許多套件做個參考:

另外一個套件:Angular Material 的 Datepicker

原本要用 Angular Material 的 Datepicker 的。可是!他沒有 range,也沒有 time,有點不符合需求,所以作罷。
不過 Angular Material Datepicker 的用法可以參考「[Angular Material完全攻略] Day 11 — 打造問卷頁面(3) — Datepicker」這篇文章。
結束!:D