The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

Angular 2 開發心得分享 (01):使用 HTML 自訂元素的注意事項

使用 Angular 2 開發網站跟以前 Angular 1 最不一樣的地方在於「網頁元件化」的觀念,網頁中所有看到的東西都將變成一個個的 directive 元件,當你將現有網頁 HTML 版型變成 Angular 2 的 Directive 元件後,Angular 2 執行時會把這些 HTML 片段編譯過,並且找出這些 HTML 片段中是否含有其他的 Directive 元件,如果有找到,就會初始化這個 Directive 元件��不過當你的 HTML 版型中有用到「自訂的 HTML 元素」或「寫錯的 HTML 元素」,執行時期就會立刻發生錯誤,這問題發生的原因與解決方法,將是本文討論的重點。

Angular 2 在編譯與剖析 HTML 片段時,必須認真看待每一個 HTML 元素 (HTML Element),只要是 HTML5 規格中定義的 HTML 元素,就會被視為 HTML 範本的一部分,而那些不是 HTML5 規格定義的元素,預設就會被視為一個 Directive 元件,並對此進一步解析成元件。

這裡我們直接透過 Angular CLI 快速建立一個 Angular 2 專案,並用 Visual Studio Code 開啟該專案:

ng new demo0920

cd demo0920

code .

ng serve

我們直接修改 AppComponent 的 Template 頁面 ( src/app/app.component.html ) 並加上一個 hgroup 元素,如下圖示:

 

接著我們來看看網頁執行的情況,你會發現我們加上 <hgroup> 元素後,網頁就跑不出來了!

 

我們按下 F12 開發者工具,切換到 Console 頁籤,此時你會看到完整的錯誤訊息:

 

我來摘要一下重要的錯誤訊息片段如下:

zone.js:344Unhandled Promise rejection: Template parse errors:
'hgroup' is not a known element:
1. If 'hgroup' is an Angular component, then verify that it is part of this module.
2. If 'hgroup' is a Web Component then add "CUSTOM_ELEMENTS_SCHEMA" to the '@NgModule.schema' of this component to suppress this message.

上次錯誤訊息寫得非常清楚,他說:「'hgroup' 並不是一個已知的元素」!

※ 補充說明 ※

早期在 HTML5 規格尚未發佈正式版的時候,當時是有 hgroup 元素的,但 HTML5 工作小組在 2013/4/2 的一次會議結論中決定從規格中移除 hgroup 元素,因此請大家不要再用這個 hgroup 元素。

由此可知,Angular 2 在解析網頁版型時,任何自訂的 HTML 標籤,預設都必須為合法的 Directive 元件才行,以我們這個例子來說,最簡單的作法當然就是不要用 hgroup 元素,你可以改寫成 <div> 或乾脆直接移除 (前提是版型不會跑掉才能直接移除),這也是建議的做法。

但如果你真的有特殊理由,必須保留這些自訂元素在 Template 裡面的話,你還是可以參考以下設定,讓自訂的 HTML 標籤可以繼續存在。

我們從 Angular 2 官方的 NgModule API 文件中可以發現,在 AppModule 設定 @NgModule 時,可以加上一個 schemas 屬性,而這個屬性可用的屬性值只有兩種:

  • NO_ERRORS_SCHEMA
    任何自訂的元素與屬性都不會提示任何錯誤訊息。
  • CUSTOM_ELEMENTS_SCHEMA
    任何自訂的元素名稱中有出現減號 ( - ) 的都是允許的元素 (例如: my-hgroup )

如果我們以本文稍早提到的這個 hgroup 元素為例,這個元素名稱並沒有出現減號,因此你必須設定 NO_ERRORS_SCHEMA 才能正常執行,設定好的畫面如下圖示:

 

設定完成之後,網頁就可以正常執行了:

 

如果想使用 Web Components 技術在 Angular 2 應用程式中,依據 W3C 的 Custom Elements 規格,你在命名自訂元素時,都應該至少加上一個 dash 符號 (就是減號) ( - )。

參考文章: How should I name my element? — WebComponents.org

 

本篇文章當然不會特別提及 Web Components 的開發,我們就稍微修改一下原本的 hgroup 標籤,改用 my-hgroup 當成自訂的元素名稱,如下圖示:

image

 

此時你就可以在 @NgModule.schema 設定 CUSTOM_ELEMENTS_SCHEMA 即可允許所有自訂元素的標籤 (但名稱必須至少有一個 dash 符號),設定好的畫面如下圖示:

 

設定好之後,Angular 2 在執行的過程中就不會再出現任何錯誤訊息了!

 

相關連結