【问题标题】:How to unsubscribe in this situation? Angular 2+?在这种情况下如何退订?角2+?
【发布时间】:2020-06-05 20:52:20
【问题描述】:
  public testArr: any = []; 
     getData() {
        this.dataS.getSensor().subscribe((data: any) => {
            this.testArr= data; 
        })
      }


this.testArr.unsubscribe()

如果我的 testArr 是数组怎么办? 现在比现在老了吗?

【问题讨论】:

    标签: angular rxjs


    【解决方案1】:

    您只能从Observable 取消订阅,testArr 不能。

    // declare a subscription
    subscription: Subscription = new Subscription();
    
    getData() {
    // reference your observable to the subscription
      this.subscription = this.dataS.getSensor().subscribe((data: any) => {
        this.testArr= data; 
          })
        }
    
    // unsubscribe when the component gets destroyed
    ngOnDestroy() {
      this.subscirption.unsubscribe();  
    }
    

    【讨论】:

      【解决方案2】:

      多个订阅变量可能会很快失控并且可能会很混乱。

      更好的方法是使用主题,它可以在每个订阅中重复使用,如下所示。

      // Declare a subscription handler
      private onDestroy$ = new Subject();
      
      getData() {
          // here we will use the onDestroy$ Subject to automatically unsubscribe
          this.dataS.getSensor()
          .pipe(takeUntil(this.onDestroy$))
          .subscribe((data: any) => {
              this.testArr= data; 
          });
      }
      
      // complete the subject when the component gets destroyed to unsubscribe
      ngOnDestroy() {
          this.onDestroy$.next();
          this.onDestroy$.complete();
      }
      

      使用最新的 Angular,使用 http 的订阅会被自动处理和清理,但在某些情况下,最好还是自己取消订阅。

      【讨论】:

      • 这是我首选的退订方法,因为您可以退订单个变量,在本例中为“onDestroy$”,使用它的所有内容也将退订
      【解决方案3】:

      您还可以使用自动取消订阅的异步管道。 https://angular.io/api/common/AsyncPipe

      component.ts

       // use your type instead of any
       data$: Observable<any>;
      
       ngOnInit() {
         this.data$ = this.dataS.getSensor();
       }
      

      template.ts

      <div *ngIf="data$ | async as data">
        // now you can use data property as you want
      </div>
      

      【讨论】:

      • data$ 是属性的名称。
      • 这是命名约定。这是一个很好的答案stackoverflow.com/questions/37671700/…
      • 在括号中 Observable 你设置了一个返回对象
      • 是的。当您发出请求 getSensor() 时,您将恢复您的模型。这将是你在 Observable 中的类型
      【解决方案4】:

      通常的方式是:定义一个订阅变量,分配订阅结果并在(组件的)detroy方法上取消订阅。

      @Component({ .... })
      export class AppComponent implements OnInit, OnDestroy {  
        
        private subscription: Subscription = new Subscription();
        public testArr: any = []; 
        
        getData() {
              this.subscription =
                this.dataS.getSensor().subscribe((data: any) => {
                  this.testArr= data; 
                  })
            }
      
      
        ngOnDestroy() {
          this.subscirption.unsubscribe();   
        }
      }  
      

      上面的一个变体是使用 Add 方法。

      this.subscription.Add ( this.dataS.getSensor().subscribe(...) );
      this.subscription.Add ( this.Observable2.subscribe(...) );
      this.subscription.Add ( this.Observable3.subscribe(...) );
      

      最后:

        ngOnDestroy() {
          this.subscirption.unsubscribe();   
        }
      

      这允许在一个订阅变量中管理多个订阅

      另一方面,我一直在尝试另一种方法,并且对我有用:

      @Component({ .... })
      export class AppComponent implements OnInit, OnDestroy {  
        
        private subscription: Subscription = new Subscription();
        public testArr: any = []; 
        
        //Define an POO "old school" event
        private onDataArrive?: () => void
        
        ngOnInit() {
            //Assign the event, with unsubscribe method.
            this.onDataArrive = () =>
              {
                //unsubscribe
                this.subscription.unsubscribe();
              }
        }
        
        getData() {
              //Assign the subscription 
              this.subscription =
                this.dataS.getSensor().subscribe((data: any) => {
                  this.testArr= data; 
                  
                  //if event is assigned, then call it
                  if (this.onDataArrive) this.onDataArrive();
                  
                  })
            }
      
      }  
      

      看起来,比仅仅在 onDestroy 方法取消订阅更“复杂”...但是,一个 observable 是一个永久监听的线程,这种方式可以在响应到达后立即取消订阅,而不是等到结束组件寿命。

      【讨论】:

        【解决方案5】:

        在组件使用后,有以下 5 种方法可以取消订阅 Angular 组件。

        • 通过将 unsubscribe() 方法与 ngOnDestroy() 生命挂钩使用。
        • 使用异步管道。
        • 通过使用 RxJs take* 运算符
        • 通过创建自定义装饰器。
        • 通过使用 TS lint。 有关退订 Angular 组件的更多信息,请参阅下面的链接 5-ways-to-unsubscribe-an-angular-component

        【讨论】:

          【解决方案6】:

          如果您使用的是 Angular HttpClient,则无需取消订阅。

          httpClient 只发送一个值然后完成。

          否则你可以使用一个装饰器,当组件被销毁https://github.com/NetanelBasal/ngx-auto-unsubscribe

          @AutoUnsubscribe()
          @Component({
           selector: 'app'
          })
          

          在这些情况下无需退订

          • 在 HttpClient 调用的情况下,因为 observable 发出一个值 (成功或错误)并自动完成。
          • 万一或ActivatedRoute订阅,因为路由器将 当组件被自动销毁时销毁它
          • 使用异步管道

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-08-22
            • 2018-04-22
            • 1970-01-01
            • 1970-01-01
            • 2022-01-23
            相关资源
            最近更新 更多