typescript 如何初始化订阅对象

7vhp5slm  于 2022-12-19  发布在  TypeScript
关注(0)|答案(6)|浏览(131)

我使用订阅从Angular 路线中获取一个参数。下面是代码:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Subscription} from 'rxjs';

@Component({
    selector: 'farm-house',
    templateUrl: './house.component.html',
    styleUrls: ['./house.component.scss']
})
export class GreenhouseComponent implements OnInit, OnDestroy {
    
    private routeSub: Subscription;
    id: string;

    constructor(private route: ActivatedRoute) {
        this.id = "";
    }

    ngOnInit(): void {
        this.routeSub = this.route.params.subscribe(params => {
            this.id = params['id'];
        });
    }

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

但问题是编译器会说:
属性“routeSub”没有初始值设定项,并且未在构造函数中明确赋值。
我的问题是,初始化Subscription对象的最佳方法是什么?

oxiaedzo

oxiaedzo1#

我提出了另一个解决方案,它使用this question中的Subscription.EMPTY

import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Subscription} from 'rxjs';

@Component({
    selector: 'farm-house',
    templateUrl: './house.component.html',
    styleUrls: ['./house.component.scss']
})
export class GreenhouseComponent implements OnInit, OnDestroy {
    
    private routeSub: Subscription;
    id: string;

    constructor(private route: ActivatedRoute) {
        this.routeSub = Subscription.EMPTY;
        this.id = "";
    }

    ngOnInit(): void {
        this.routeSub = this.route.params.subscribe(params => {
            this.id = params['id'];
        });
    }

    ngOnDestroy(): void {
        if(this.routeSub) {
            this.routeSub.unsubscribe();
        }
    }
}
nhaq1z21

nhaq1z212#

大多数情况下,它的应该是足够的检查订阅之前取消订阅.

ngOnDestroy() {
     if(this.routeSub) {
       this.routeSub.unsubscribe();
     }
 }

在您的情况下,不需要初始化订阅,因为您已经在ngOnInit()中调用了subscribe方法。可能会出现错误,因为您直接在 Subscription 上调用unsubscribe(),而没有检查它是否已初始化。

tzxcd3kk

tzxcd3kk3#

应该只是
第一个月
这对我很有效。

t5fffqht

t5fffqht4#

如果你声明了routeSub: any;,编译器不会抱怨。看到它在这个职位上完成,我为我工作

gjmwrych

gjmwrych5#

方式一:
我只订阅了一份。

private routeSub?: Subscription;
    ngOnInit(): void {
        this.routeSub = this.route.params.subscribe(params => {
            this.id = params['id'];
        });
    }

    
    ngOnDestroy(): void {
       // no need to do a separate if, use ? it is more readable
        this.routeSub?.unsubscribe();
    }

第二种方法,如果我有多个订阅,我会用一次清理来清理它们:

private destroyed$ = new Subject<boolean>();

Somewhere() {
combineLatest([userService.spaceName$, userService.userName$])
      .pipe(takeUntil(this.destroyed$))
      .subscribe(([space, username]) => {do something...}
    }

ngOnDestroy() {
    this.destroyed$.next(true);
    this.destroyed$.complete();
  }

第三条路----大多是最好的路

myObservable$: Observable<myInterface>;

ngOnInit() {
   this.myObservable$ = this.myservice.someObservable$;
}

...    html ...
<ng-container *ngIf='myObservable$ | async as list; else simpleInput'>

这最后一个过程与onPush一起工作,你永远不会忘记取消订阅。
请注意,第一种方式是非常方便的,当您订阅和取消订阅作为呼叫的一部分,甚至与第二种方式相结合:

pollUser(): void {
    // if it has been hear before unsubcribe, otherwise skip it.
    this.subscription?.unsubscribe();

    this.subscription= this.someservice(serviceParameters)
      .pipe(takeUntil(this.destroyed$))
      .subscribe(result => {
            this.useResult = result;
        });
    }
sg24os4d

sg24os4d6#

这里不需要取消订阅,因为Angular会为您销毁此特定订阅。

相关问题