2016-03-15 66 views
0

我有一个全球服务,旨在将单个引用分发给单个但可能更改的对象。通常情况下,我会通过组件的“正常”输入参数来执行此操作,但由于涉及到路由器,因此这是不可能的。至少下面的代码片段没有做任何事情对我来说,即使不引发错误:在服务中共享HTTP资源的相同实例?

<!-- All possible instances of this outlet have "project" set as input --> 
<router-outlet [project]="project"></router-outlet> 

因为我不能做这种方式(!请告诉我,否则如果我可以),我创建了一个服务我想用来在所有请求者中共享同一个实例。除此之外,如果我可以将所有可观测数据用于更新新项目(如果需要不同的项目ID),我会爱上它。显然,代码不这样做呢,因为它取代了整个缓存可观察:

/** 
* Wraps access to a whole project. 
*/ 
@Injectable() 
export class ProjectService { 
    // The same instance should be shared among all projects 
    private cache : { 
     observable : Observable<Project>, 
     id : string 
    }; 

    /** 
    * @param _http Dependently injected by Angular2 
    */ 
    constructor(private _http: Http) { } 

    /** 
    * @param id The id of the project to retrieve 
    * @return An observable that updates itself if the selected project changes. 
    */ 
    getProject(id : string) : Observable<Project> { 
     if (!this.cache || this.cache.id != id) { 
      let obs = this._http.get('/api/project/' + id) 
       .do(res => console.log(res.json())) 
       .map(res => new Project(res.json())) 
       .catch(this.handleError); 

      this.cache = { 
       observable : obs, 
       id : id 
      } 
     } 

     return this.cache.observable.share(); 
    } 

    private handleError (error: Response) { 
     // in a real world app, we may send the error to some remote logging infrastructure 
     // instead of just logging it to the console 
     console.error(error); 
     return Observable.throw(error); 
    } 
} 

我希望我可以通过调用观察到share()避免后续的HTTP请求,但我想我missunderstood东西:目前我的应用使用相同的ID为每个致电getProject()的用户发出新请求。

我怎么可能让服务:

  • 没有做的第一后任何后续的HTTP请求,除非明确地触发?
  • 如果请求的ID更改,则使用新资源实例更新所有订阅的Observable?

回答

1

我会更新您的服务像什么:

getProject(id : string) : Observable<Project> { 
    if (!this.cache || this.cache.id != id) { 
    return this._http.get('/api/project/' + id) 
     .map(res => new Project(res.json())) 
     .do((data) => { 
      if (!this.cache) { 
      this.cache = {}; 
      } 
      this.cache[id] = data; 
     }) 
     .catch(this.handleError); 
    } else { 
    return Observable.of(this.cache[id]); 
    } 
} 

如果你想通知对数据进行更新的组件,你可以充分利用专用可观察。在设置缓存的同时,您可以使用关联的观察者触发事件......组件可以在要通知的观察值上订阅。

1

这应该做你想要

getProject(id : string) : Observable<Project> { 
    if (!this.cache || this.cache.id != id) { 
     return this._http.get('/api/project/' + id) 
      .do(res => console.log(res.json())) 
      .map(res => new Project(res.json())) 
      .map(res => return { 
       observable : obs, 
       id : id 
      }) 
      .do(res => this.cache = res) 
      .catch(this.handleError); 
    } else { 
     return Observable.of(this.cache); 
    } 
}