參考地址:https://github.com/kittencup/angular2-ama-cn/issues/18
前言:
templateUrl
表示的是組件在瀏覽器中運行時依賴的模板地址,所以在templateUrl
這里並不能填寫./xxx.html
這種路徑,你要從瀏覽器的路徑考慮它
src
index.html
index.js // 可能是打包后生成的
components
button
button.ts
button.html
當你打開index.html
時你想一下,加載
button.html
的路徑是什么,/components/button/button.html
所以對於你的button.ts
里的templateUrl
應該寫成 /components/button/button.html
由此可見,templateUrl
的路徑應該是根據你執行的html文件路徑來計算
問題
如果每個component
文件夾內組件的templateUrl
都需要寫上/components
是不是很麻煩,當然在這里路徑還是比較短而簡單的,如果路徑很長呢/a/b/c/d/e/f/components
那么你是不是在每個組件內都要寫上那么長的地址,而且后期修改起來也要每個文件都改一下。
解決方案
Angular 2 幫你想到了這個問題,可使用 package:
或者asset:
占位符,這2個占位符默認對應的值是/packages
,當你設置templateUrl:'package:/button/button.html'
,在運行時這個地址會被替換為/packages/button/button.html
,在這里我們需要修改一下默認的占位符地址,通過重設Token
為PACKAGE_ROOT_URL
的provide
import {provide,PACKAGE_ROOT_URL} from 'angular2/core';
bootstrap(App,[provide(PACKAGE_ROOT_URL,{useValue: '/components'})])
這樣在運行時編譯出得地址就變為 /components/button/button.html
更復雜的問題
package:
或者asset:
占位符可以解決開發時運行時加載的路徑,當項目發布到正式環境后,我們的靜態文件應該會在CDN上,當然通過PACKAGE_ROOT_URL
也是能解決這個路徑問題,但是不夠靈活,如果我想templateUrl
從http://cdn.template.kittencup.com
加載,而styleUrl
到http://cdn.style.kittencup.com
加載,那么單單用一個PACKAGE_ROOT_URL
是無法解決的
解決方案
在Angular 2源碼中無論templateUrl
和styleUrl
在加載前都會通過UrlResolver
對象來進行處理,UrlResolver
對象是通過依賴注入獲取的,源碼在 src/compiler/url_resolver.ts ,默認的UrlResolver
是根據PACKAGE_ROOT_URL
的值來替換package:
或者asset:
占位符,所以我們可以重設UrlResolver
,代碼如下
一、
@Component({ selector: "hz-stepbody", templateUrl: "dm_template.html"//注意,這里不能用/dm_template.html }) class Stepbody { }
import {UrlResolver} from 'angular2/compiler'; class MyUrlResolver extends UrlResolver { resolve(baseUrl: string, url: string): string { if (url.substr(-4) === '.css') { return super.resolve('http://cdn.style.kittencup.com', url); }else if(url.substr(-5) === '.html'){ return super.resolve('http://cdn.template.kittencup.com', url); } return super.resolve(baseUrl, url); } } bootstrap(App, [provide(UrlResolver, {useClass: MyUrlResolver})]);
二、
@Component({ selector: "hz-stepbody", templateUrl: "mytemplate:dm_template.html" }) class Stepbody { }
import {provide, PACKAGE_ROOT_URL} from 'angular2/core'; import {UrlResolver} from 'angular2/compiler'; class MyUrlResolver extends UrlResolver { resolve(baseUrl: string, url: string): string { var resolvedUrl = url; if (url.substr(0, 6) == "mytemplate") { resolvedUrl = resolvedUrl.replace("mytemplate:", "/template/gz/"); }else { resolvedUrl = super.resolve(baseUrl, url); } return resolvedUrl; } }