填充数组

时间:2017-09-28 13:40:28

标签: angular typescript

我在angular 4应用程序中有一个服务,使用以下构造函数:

constructor(private readonly http: Http) {
    this.http.get(this.originUrl + 'api/ProductCategories/').subscribe(result => {
        this.categories = result.json();
    });
}

以及此服务中的一项功能,以获取一个类别ID。

findCategory(fullSlug: string): number {
    return this.categories.filter(c=>c.fullSlug == fullSlug)[0].id;
}

我需要在填充类别列表后从组件中调用此函数。应用程序加载一次后,这是正常的,因为服务是从app.module加载的,但是当我重新加载页面时(F5)我在findCategory函数中得到错误“无法读取未定义的属性'过滤器'。

感谢。

2 个答案:

答案 0 :(得分:1)

我的this.categories属性正在填充 async ,因此在您无法从服务内部控制的其他公共方法中使用它时,需要考虑到这一点。< / p>

<强>更新 由于在这种情况下证明数据仅从数据源检索一次是重要的,因此我建议从服务中完全可观察到。这意味着服务将始终返回可观察的结果,并始终让消费者处理订阅。

仅加载数据一次的技巧是使用share运算符。它会使categories$可观察的read more on the topic here)。简而言之 - 它只会转到数据源一次,然后让所有订阅者共享已经检索到的结果(参见下面的更新代码)。

我建议将订阅类别的责任委托给服务的使用者,然后将要进行过滤的数据作为参数添加到filter函数中。

<击>

这可以确保您在进行过滤时始终使用加载的数据。

在服务中(暂时为YourService.ts):

originUrl = "....";
categories$: Observable<YourCategoryType[]>;

constructor(private readonly http: Http) {
  this.categories$ = this.http.get(this.originUrl + 'api/ProductCategories/')
    .map(res => res.json())
    .share(); // <- Makes sure the call is only made ones, then re-uses the result
}

findCategory(fullSlug: string): Observable<number> {
    return this.categories$
      .map(cats => cats.filter(cat => cat.fullSlug === fullSlug)[0].id);
}

在消费者中,例如组件:

categoryId: number;

constructor(private yourService: YourService) {}

someMethod(fullSlug: string) {
  this.yourService
    .findCategory(fullSlug)
      .subscribe(catId => this.categoryId = catId);
}

答案 1 :(得分:0)

它真的无法预测,当你在服务的构造函数中使用它时,你无法控制http请求。

我建议你有一个&#34;帮助&#34;而不是方法,以便您可以控制流量。在该辅助方法中,我们只需检查value是否为categories$。如果是,请进行http呼叫。然后在您的服务中使用该方法并执行您的魔法;)在您的服务中这样的事情:

undefined

然后,如上所述,在您的其他服务方法中,只需调用上述服务方法......例如,当您从组件中调用categories$: Observable<ProductCategory[]> getCategories() { if(this.categories$ === undefined) { this.categories$ = this.http.get(this.originUrl + 'api/ProductCategories/') .map(res => res.json()) } return this.categories$ } 时,这将在您的服务中进行:

findCategory

..您可以在组件中订阅哪个结果。