Angular2 how do they save to cache?

2019-07-21 02:55发布

I was trying out the 5 min Anuglar2 Tutorial and when it said that you are able to use external templates I tried it.

My component looks like this

import {Component, Template, bootstrap} from 'angular2/angular2';

// Annotation section
@Component({
  selector: 'my-app'
})
@Template({
  url: "component.html"
})
// Component controller
class MyAppComponent {
  constructor() {
    this.name = 'Alice';
  }
}

bootstrap(MyAppComponent);

I had a mistake in my external template and fixed it, but the HTML file was still cached so I couldn't the effects in the browser.

Figuring out how they cache it I looked at the code on Github

I found this

#angular/modules/angular2/src/core/compiler/template_loader.js

@Injectable()
export class TemplateLoader {
  _xhr: XHR;
  _htmlCache: StringMap;
  _baseUrls: Map<Type, string>;
  _urlCache: Map<Type, string>;
  _urlResolver: UrlResolver;

  constructor(xhr: XHR, urlResolver: UrlResolver) {
    this._xhr = xhr;
    this._urlResolver = urlResolver;
    this._htmlCache = StringMapWrapper.create();
    this._baseUrls = MapWrapper.create();
    this._urlCache = MapWrapper.create();
  }

  // TODO(vicb): union type: return an Element or a Promise<Element>
  load(template: Template) {
    if (isPresent(template.inline)) {
      return DOM.createTemplate(template.inline);
    }

    if (isPresent(template.url)) {
      var url = this.getTemplateUrl(template);
      var promise = StringMapWrapper.get(this._htmlCache, url);

      if (isBlank(promise)) {
        promise = this._xhr.get(url).then(function (html) {
          var template = DOM.createTemplate(html);
          return template;
        });
        StringMapWrapper.set(this._htmlCache, url, promise);
      }

      return promise;
    }

So I check out the StringMapWrapper angular/modules/angular2/src/facade/collection.es6

and for set the code is just

static set(map, key, value) {
    map[key] = value;
  }

I saw that the StringMapWrapper comes from global

export var StringMap = global.Object;

But looking in angular/modules/angular2/src/facade/lang.es6 I cant figure out where the Map is cached.

I do not know much about the caching process and hope someone could explain how they do it in this case.

2条回答
啃猪蹄的小仙女
2楼-- · 2019-07-21 03:28

StringMapWrapper.create() creates an object literal {}. They use something like StringMapWrapper for Dart support where these primitives are created differently in the other language. In short all they're doing is this

var cache = {};
xhr(templateUrl).then(template => {
  cache[templateUrl] = template;
  return template;
})
查看更多
Luminary・发光体
3楼-- · 2019-07-21 03:47

@gdi2290 had nearly answered your question, and if you want to understand more about Cache Management in JavaScript/TypeScript, please see my post here http://www.ravinderpayal.com/blogs/12Jan2017-Ajax-Cache-Mangement-Angular2-Service.html .

There is a step by step explanation of a cache management class which acts as Layer to AJAX, and can be injected to components as Service. Here's a synopsis of code from class:-

 private loadPostCache(link:string){
     if(!this.loading[link]){
               this.loading[link]=true;
               this.links[link].forEach(a=>this.dataObserver[a].next(false));
               this.http.get(link)
                   .map(this.setValue)
                   .catch(this.handleError).subscribe(
                   values => {
                       this.data[link] = values;
                       delete this.loading[link];
                       this.links[link].forEach(a=>this.dataObserver[a].next(false));
                   },
                   error => {
                       delete this.loading[link];
                   }
               );
           }
    }

    private setValue(res: Response) {
        return res.json() || { };
    }

    private handleError (error: Response | any) {
        // In a real world app, we might use a remote logging infrastructure
        let errMsg: string;
        if (error instanceof Response) {
            const body = error.json() || '';
            const err = body.error || JSON.stringify(body);
            errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
        } else {
            errMsg = error.message ? error.message : error.toString();
        }
        console.error(errMsg);
        return Observable.throw(errMsg);
    }

    postCache(link:string): Observable<Object>{

         return Observable.create(observer=> {
             if(this.data.hasOwnProperty(link)){
                 observer.next(this.data[link]);
             }
             else{
                 let _observable=Observable.create(_observer=>{
                     this.counter=this.counter+1;
                     this.dataObserver[this.counter]=_observer;
                     this.links.hasOwnProperty(link)?this.links[link].push(this.counter):(this.links[link]=[this.counter]);
                     _observer.next(false);
                 });
                 this.loadPostCache(link);
                 _observable.subscribe(status=>{
                     if(status){
                         observer.next(this.data[link]);
                     }
                     }
                 );
             }
            });
        }
查看更多
登录 后发表回答