如何只发送一次查询并使结果可用于所有组件? (应该很简单)
How can I send query only once and make result available to all components? (should be quite simple)
我正在为我的个人项目使用 angular 2。所以这是带有一些 sudo 代码的简化场景。
app
|- main.ts /* bootstrap the app */
|- app.component.ts /* basically with a template: `<nav></nav>
| <router-outlet></router-outlet>`.
| And also have providers: [CatService] */
|- nav.component.ts /* a navigation bar where each cat's name is an option.
| ngOnInit(){ this._catService.getCats().then(assignCats) } */
|
|- cat.components.ts /* show the cat's detail selected from the nav component
ngOnInit(){ this._catService.getCat().then(assignCat); } */
|
|- cat.service.ts /* getCats() method to send query to a database for all the cats */
好的。我希望这看起来不会太复杂。
唯一的问题是,我正在调用 this._catService.getCats()
,它将查询发送到 nav.component
和 cat.component
中的数据库。但实际上没有必要发送两次查询,因为我已经知道数据不会经常更改。我现在只能想到两种处理方式:
在 this._catService.getCats()
中缓存数据库调用的结果,以便在第二次调用时,它可以 return 缓存的值而不是发送第二个查询。
在 app.component
处进行查询,然后将结果作为 @input
传递给 nav
和 cat
。但这意味着以后如果我有一个新组件,我也必须将结果传递给它吗?然后最终 app.component
的模板可能会变成这样的:<nav [cats]="queriedCats"></nav>
、<cat [cats]="queriedCats"></cat>
、<somecomponent [cats]="queriedCats"></somecomponent>
...这对我来说真的很糟糕。
你怎么看?首选哪种方式?
Which way is the prefered way to do it?
第一种方式更适合并且更好地利用了 Angular 的依赖注入机制。
I am calling the this._catService.getCats() which sends query to the database in both nav.component and cat.component. But there actually has no point sending the query twice as I already know the data is not going to change often.
查询结果变化不大,其实是你自己的实现细节_catService
:没必要让其他组件知道,把那个细节封装在里面。
而且,你自己也说过,查询结果几乎是不变的,但仍然在变化(或者可能开始更频繁地变化)。让服务来处理这个问题,让系统的其余部分从负担中解脱出来。
Should I still return a promise from getCats()
?
是的,你可以 return Promise
s。一个很好的例子可以在 angular 文档的 demo plunker (check the app/hero.service.ts
file, method getHeroes()
) of the Services tutorial page 中找到。
您也可以 return Observable
:这在 Angular2 中更常见,而 Observable
实际上是 return由 Htto#get()
编辑。 Angular 文档在这里也解释得很好:RxJS Observable of HTTP Responses.
他们也有一个 demo plunker(再次检查 app/hero.service.ts
文件,方法 getHeroes()
)展示如何 return Observable
s。打开两个demo对比一下,我觉得对你很有用。
我将为此利用 Observables 的 do
运算符。这是一个示例:
export class CatsService {
getCats() {
if (this.cachedCats) {
return Observable.of(this.cachedCats);
} else {
return this.http.get(...)
.map(res => res.json())
.do(data => {
this.cachedCats = data;
})
}
}
我正在为我的个人项目使用 angular 2。所以这是带有一些 sudo 代码的简化场景。
app
|- main.ts /* bootstrap the app */
|- app.component.ts /* basically with a template: `<nav></nav>
| <router-outlet></router-outlet>`.
| And also have providers: [CatService] */
|- nav.component.ts /* a navigation bar where each cat's name is an option.
| ngOnInit(){ this._catService.getCats().then(assignCats) } */
|
|- cat.components.ts /* show the cat's detail selected from the nav component
ngOnInit(){ this._catService.getCat().then(assignCat); } */
|
|- cat.service.ts /* getCats() method to send query to a database for all the cats */
好的。我希望这看起来不会太复杂。
唯一的问题是,我正在调用 this._catService.getCats()
,它将查询发送到 nav.component
和 cat.component
中的数据库。但实际上没有必要发送两次查询,因为我已经知道数据不会经常更改。我现在只能想到两种处理方式:
在
this._catService.getCats()
中缓存数据库调用的结果,以便在第二次调用时,它可以 return 缓存的值而不是发送第二个查询。在
app.component
处进行查询,然后将结果作为@input
传递给nav
和cat
。但这意味着以后如果我有一个新组件,我也必须将结果传递给它吗?然后最终app.component
的模板可能会变成这样的:<nav [cats]="queriedCats"></nav>
、<cat [cats]="queriedCats"></cat>
、<somecomponent [cats]="queriedCats"></somecomponent>
...这对我来说真的很糟糕。
你怎么看?首选哪种方式?
Which way is the prefered way to do it?
第一种方式更适合并且更好地利用了 Angular 的依赖注入机制。
I am calling the this._catService.getCats() which sends query to the database in both nav.component and cat.component. But there actually has no point sending the query twice as I already know the data is not going to change often.
查询结果变化不大,其实是你自己的实现细节_catService
:没必要让其他组件知道,把那个细节封装在里面。
而且,你自己也说过,查询结果几乎是不变的,但仍然在变化(或者可能开始更频繁地变化)。让服务来处理这个问题,让系统的其余部分从负担中解脱出来。
Should I still return a promise from
getCats()
?
是的,你可以 return Promise
s。一个很好的例子可以在 angular 文档的 demo plunker (check the app/hero.service.ts
file, method getHeroes()
) of the Services tutorial page 中找到。
您也可以 return Observable
:这在 Angular2 中更常见,而 Observable
实际上是 return由 Htto#get()
编辑。 Angular 文档在这里也解释得很好:RxJS Observable of HTTP Responses.
他们也有一个 demo plunker(再次检查 app/hero.service.ts
文件,方法 getHeroes()
)展示如何 return Observable
s。打开两个demo对比一下,我觉得对你很有用。
我将为此利用 Observables 的 do
运算符。这是一个示例:
export class CatsService {
getCats() {
if (this.cachedCats) {
return Observable.of(this.cachedCats);
} else {
return this.http.get(...)
.map(res => res.json())
.do(data => {
this.cachedCats = data;
})
}
}