如何解決Angular 2 的templateUrl和styleUrl的路徑問題?


參考地址: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,在這里我們需要修改一下默認的占位符地址,通過重設TokenPACKAGE_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也是能解決這個路徑問題,但是不夠靈活,如果我想templateUrlhttp://cdn.template.kittencup.com加載,而styleUrlhttp://cdn.style.kittencup.com加載,那么單單用一個PACKAGE_ROOT_URL是無法解決的

解決方案

在Angular 2源碼中無論templateUrlstyleUrl在加載前都會通過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;
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM