angular2中的$ templateCache?

时间:2016-05-02 06:04:11

标签: caching angular angular2-template

我需要angular1.x $templateCache的等效解决方案: 在应用程序启动时,我必须根据用户的配置文件,角色,权限,语言和当前位置来翻译和配置所有html视图。我希望在服务器端使用ASP.NET Razor语法和工具在一个请求中完成此操作(不是每个组件都有一个)。此请求应将所有可以使用的模板放入angular2客户端缓存中。从现在开始,每个引用其模板的组件将首先从此缓存中提供(如果可用)。在Angular1.x中,很容易在一个请求中加载所有模板,由<script id="myView.html" type="text/ng-template">...</script>分隔。在将它们放入缓存之前,我必须通过调用$compiler()来编译每个模板。 我怎样才能在Angular2中实现这一目标? 我可以想象的一种可能的解决方案是,如果Angular2支持Component templateUrl作为function()。这样我就可以构建自己的缓存。

1 个答案:

答案 0 :(得分:1)

经过一些研究并深入研究angular2源代码,$templateCache in Angular 2?指出了正确的解决方案。我必须通过provide():

注册一个新的自定义Http和一个自定义XHR实现
 providers: [HTTP_PROVIDERS, 
                provide(Http, {
                        useFactory: (xhrBackend: XHRBackend, requestOptions: RequestOptions) => new HttpInterceptor(xhrBackend, requestOptions),
                        deps: [XHRBackend, RequestOptions]
                    }),
                provide(XHR, { 
                    useFactory: (http: Http) => new XHRInterceptor(http), deps: [Http] 
                })],

每次angular2通过Compontent的tempateUrl加载html temlates时,注入XHRInterceptor(XHR接口的实现)并由angular2内部使用。因为我们将自定义Http实现注入XHRInterceptor构造函数并通过HttpInterceptor委托所有get请求,所以我们可以完全控制来自应用程序的所有http请求:

export class XHRInterceptor extends XHR {
    constructor(private _http: Http) {
        super()
    }
    get(url: string): Promise<string> {
        var completer: PromiseCompleter<string> = PromiseWrapper.completer();
        this._http.get(url).map(data=> {
            return data.text();
        }).subscribe( data => {
            completer.resolve(data);
        }, error=>{
            completer.reject(`Failed to load ${url}`, null);
        });
        return completer.promise;
    }
}

这是我的HttpInterceptor类:

export class HttpInterceptor extends Http {

    constructor(backend: ConnectionBackend, defaultOptions: RequestOptions) {
        super(backend, defaultOptions);
    }

    request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
        if (typeof url === "string") {
            return this.interceptResult(super.request(this.interceptUrl(url), this.interceptOptions(options)));
        } else {
            return this.interceptResult(super.request(url, this.interceptOptions(options)));
        }
    }
    get(url: string, options?: RequestOptionsArgs): Observable<Response> {
        return this.interceptResult(super.get(this.interceptUrl(url), this.interceptOptions(options)));
    }

    post(url: string, body: string, options?: RequestOptionsArgs): Observable<Response> {
        return this.interceptResult(super.post(this.interceptUrl(url), body, this.interceptOptions(options)));
    }

    put(url: string, body: string, options?: RequestOptionsArgs): Observable<Response> {
        return this.interceptResult(super.put(this.interceptUrl(url), body, this.interceptOptions(options)));
    }

    delete(url: string, options?: RequestOptionsArgs): Observable<Response> {
        return this.interceptResult(super.delete(this.interceptUrl(url), this.interceptOptions(options)));
    }

    interceptUrl(url: string): string {
        // Do some stuff with the url....
        //...
        return url;
    }

    interceptOptions(options?: RequestOptionsArgs): RequestOptionsArgs {
        // prepare options...
        if (options == null) {
            options = new RequestOptions();
        }
        if (options.headers == null) {
            options.headers = new Headers();
        }

        // insert some custom headers...
        // options.headers.append('Content-Type', 'application/json');

        return options;
    }

    interceptResult(observable: Observable<Response>): Observable<Response> {
        // Do some stuff with the result...
        // ...
        return observable;
    }
}