如何使用 BehaviorSubject 获取 All Items 和 Single Item?

How to use BehaviourSubject to get All Items and Single Item?

我使用的是 BehaviorSubject 下面的文章:

https://coryrylan.com/blog/angular-observable-data-services

在本文中,作者使用 loadAll() 加载所有项目,并使用 load() 加载单个条目。 load() 然后会将检索到的项目推送到 dataStore 中,然后将其发送到 next(...) 函数中,以便所有订阅者都得到通知。我不确定 100% 确定这是否是正确的方法。我不确定为什么,但我觉得这就是我们设计服务的方式似乎很奇怪。我可能是错的,因为我是 BehaviorSubject 的新手。所以我的问题是,这是检索所有项目和单个项目的正确方法还是有更好的方法?

据我所见... 方式 太多开发人员在使用 BehaviorSubject 时,更简单的解决方案就足够了。

BehaviorSubject 仅在您有复杂的要求以在数据未绑定时监视数据更改时才真正需要。否则,简单的数据绑定会为您处理变化。

这是我在服务中获取所有和获取一个的代码:

getProducts(): Observable<IProduct[]> {
    return this._http.get<IProduct[]>(this._productUrl)
        .do(data => console.log('All: ' + JSON.stringify(data)))
        .catch(this.handleError);
}

getProduct(id: number): Observable<IProduct> {
    return this.getProducts()
        .map((products: IProduct[]) => products.find(p => p.productId === id));
}

我修改了 OP 提供的 link 的 plunker,我的结果在这里:https://plnkr.co/edit/r5PMFprgoWbzmFPTK3xN?p=preview

请注意,它提供了与 NO BehaviorSubject 相同的基本功能和更简化的代码。

可观察、主题和行为主题

如果您只关心数据检索,那么 DeborahK 的回答就很正确了。通常,我轻描淡写地说 "typically",HTTP 请求是标准可观察的,这意味着请求发出,返回,returns 一些数据,并且在进行新订阅之前不会再次触发给它。对于大多数可观察到的模式,标准 Observable 类型非常适合这项工作。

最简单的思考方式就是只看名字;可观察的。如果您所做的只是 'getting' 数据,那么 Observable 就是您想要的。但是,如果您发现需要在实例化后操作数据流,那么 SubjectBehaviorSubject 可能是合适的选择。 SubjectBehaviorSubject 之间的区别在于 Subject 确实必须具有初始值,其中 BehaviorSubject 在实例化时被赋予初始值。

SubjectBehaviorSubject 的用例的一个很好的例子是一个布尔值,它在整个站点中用于告诉应用程序模式何时应该可见或不可见。由于多个组件可以改变 Modal 可见性的状态,因此您需要一个可以改变的 BehaviorSubject,触发父组件显示模态。

Subject 的另一个很好的例子是搜索栏,它向整个应用程序的其他组件宣传其内容。这里的关键是您正在向流发送新值以供应用程序中的其他 components/services 观察。

我要说的最后一件事是,从技术上讲,以上所有内容都属于 Observable 的类别。我认为这就是很多混乱发生的地方。

推送数据

关于您的问题,我注意到的另一件事是,您似乎实际上是在尝试解决 Angular 本身不一定能解决的问题。如果您的 "backend" 中有非常动态的数据,您希望将其推送到前端,那么您可能需要查看 websocket 套接字服务器。这听起来比实际要复杂得多,但本质上它允许您的服务器将 "push" 数据发送到您的应用程序。如果它是安全数据,我建议使用您的服务器推送 "updates available" 消息,然后让应用程序安全地为更新的数据发出 HTTP 请求。不要通过网络套接字发送安全信息。 Here is a great resource 用于在节点服务器内使用套接字 IO 并推送到 Angular 应用程序的 websocket。那里有很多。