【问题标题】:How to use BehaviourSubject to get All Items and Single Item?如何使用 BehaviourSubject 获取所有项目和单个项目?
【发布时间】:2017-08-02 23:26:11
【问题描述】:

我在这里使用文章后面的BehaviorSubject

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

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

【问题讨论】:

    标签: angular rxjs observable behaviorsubject


    【解决方案1】:

    从我所看到的... 方式 太多的开发人员正在使用 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 提供的链接修改了 plunker,我的结果在这里:https://plnkr.co/edit/r5PMFprgoWbzmFPTK3xN?p=preview

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

    【讨论】:

    • 我确实需要注意数据变化。
    • 我根据发布的文章提出问题。想象一下这篇文章随着时间的推移返回了大量数据。
    • @deborak 我没有对数据做任何特别的事情。通过 HTTP 检索它,然后将其映射到某个实体,最后使用 ngFor 绑定它。数据会经常变化。
    • 然后你的绑定会为你处理它......你不需要 BehaviorSubject。我只是考虑在没有 BehaviorSubject 的情况下重写 Cory 的示例以显示我的意思……但它似乎无法连接到它正在使用的 mockapi 服务。你能运行 plunker 吗?我得到:Failed to load resource: the server responded with a status of 503 (Service Unavailable)
    • 如果你有兴趣,你可以看看我的例子:github.com/DeborahK/Angular-Routing
    【解决方案2】:

    可观察、主题和行为主题

    Difference Between Observable and Subject

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

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

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

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

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

    推送数据

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

    【讨论】:

    • 谢谢。这就说得通了。但是,我不打算推​​送数据。
    • 我会说您的两个示例可以利用 Angular 的更改检测和绑定来完成,而无需 BehaviorSubject。
    • 它们可能是,但这取决于应用程序结构。例如,尝试在不是直接父/子的组件之间进行通信,甚至在父模块和延迟加载模块之间进行通信,使用标准数据绑定变得非常困难。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-01
    • 2013-10-17
    • 2017-05-10
    • 2019-11-07
    • 1970-01-01
    相关资源
    最近更新 更多