Angular 使用主题值时的可观察与订阅

Angular 使用主题值时的可观察与订阅,angular,rxjs,Angular,Rxjs,我对Angular很陌生,从我所知道的Subject是用于多播的标准类。在尝试这个类时,我发现有两种(可能更多)方法可以处理其值的变化 使用可观察的直接在组件内键入对象 在这种方法中,可观察的在组件中声明如下: foo$ : Observable<boolean>; 其中,订阅的初始化如下所示: constructor(private fbs: FooBarService) { this.s = fbs.fooObservable.subscribe(v => thi

我对Angular很陌生,从我所知道的
Subject
是用于多播的标准类。在尝试这个类时,我发现有两种(可能更多)方法可以处理其值的变化

  • 使用
    可观察的
    直接在组件内键入对象

    在这种方法中,
    可观察的
    在组件中声明如下:

    foo$ : Observable<boolean>;
    
    其中,订阅的初始化如下所示:

    constructor(private fbs: FooBarService) {
        this.s = fbs.fooObservable.subscribe(v => this.foo = v);
        //  this.s.unsubscribe() is called within ngOnDestroy()
    }
    
    然后html将使用如下代码:

    <p *ngIf="foo">Bar!</p>
    
    酒吧

  • 除了个人偏好之外,有没有其他理由选择这两种方法中的任何一种

    除了个人偏好之外,有没有其他理由选择这两种方法中的任何一种

    这类问题在这里是离题的,但给出一般性的答案对社区来说是有价值的。这两者之间有足够的区别,应该加以讨论

    一种方法称为反应组件,另一种方法称为有状态组件

    活性成分 该视图使用
    async
    管道处理来自观察对象的数据表示。如果组件仅使用可观察对象和
    async
    管道进行表示,则该组件是无状态的,并通过视图自动对更改作出反应。这有助于为模板创建干燥的感觉

    这种方法有以下优点

    • 不太可能出现“检查后表达式已更改”错误
    • 更容易通过可观察对象表示服务或存储的外部状态
    • 使用
      OnPush
      更改通知更容易
    • 通过设计,这种方法创建了一个响应性更强的组件,开发人员可以用更少的精力对更改做出反应
    这种方法有以下缺点

    • 当开发人员不理解反应式编程时,他们可能会编写
      data.subscribe(value=>this.value=value)
    • 当多个观测值被合并、切换或组合时,如果不解释原因,源代码可能很难理解
    • 引入内存泄漏和订阅丢失的风险
    • 开发人员有时可以在不了解所有副作用的情况下使用操作符。使用
      mergeMap()
      而不是
      switchMap()
      作为示例
    • 你必须追踪可观察物的生命周期
    • IDE编辑器很难自动完成类型。比如,<代码>将创建大多数IDE中类型未知的视图变量数据
    • 陡峭的学习曲线。RXJS不容易掌握
    • 使用
      调试器进行调试比较困难因为组件没有要调试的状态
    • 单元测试比较困难。没有组件状态可以断言它是正确的
    有状态组件 当组件具有视图模板中使用的属性时,该组件是有状态的。为了表示视图中的更改,必须更改零部件的内部状态,这是角度视图中零部件的默认类型

    这种方法有以下优点

    • 开发、维护和阅读源代码更容易
    • @Input()
      绑定首先是有状态的
    • IDE具有更好的组件属性自动完成功能
    • 有一个更容易的学习曲线。无需学习第三方图书馆
    • 使用
      调试器更容易”,因为您可以看到零部件的当前状态
    • 单元测试更容易
    这种方法有以下缺点

    • 从服务使用外部状态时,最有可能出现“检查后表达式已更改”错误
    • 当您混入可观察对象时,
      subscribe()
      调用会使源代码变得杂乱无章
    • 您必须手动将反应流转换为组件状态,并编写类似于
      data.subscribe(value=>this.data=value)
      的代码
    • 当使用外部观察时,变化检测成为一个挑战
    • 需要更多的代码行来创建一个响应组件,该组件可以对外部事件和可观察到的情况做出反应
    结论 在决定使用这两种方法中的哪一种时。我建议从有状态组件开始,但要将您的技能提高到反应式组件


    根据我的经验,反应性组件是一种选择,因为它们是可观察流的目的地。这些组件将可观察对象集合在一起,创建数据的响应视图,并自动对这些流中的更改做出反应。同时,将数据合并为目的地更像是一种角度上的体系结构设计。因此,这是一个更广泛的讨论和话题,但继续学习,你就会达到目的。

    主题与可观察的主要区别在于,它保留一个状态——保留对观察者的引用,而可观察只是一个函数。您应该阅读一些文档,因为您的问题太广泛,太难回答。谢谢您的深入回答!正如你可能知道的那样,我在angular/web方面是个新手,所以这确实非常有用
    constructor(private fbs: FooBarService) {
        this.s = fbs.fooObservable.subscribe(v => this.foo = v);
        //  this.s.unsubscribe() is called within ngOnDestroy()
    }
    
    <p *ngIf="foo">Bar!</p>