簡體   English   中英

從Observable的訂閱中獲取更新的值

[英]Getting updated values from Observable's subscription

我注意到有關Angular 2中Observables的一些內容,我無法解釋,並希望一個好的模型可以揭示我。

我的理解是,在訂閱Observable時,你基本上有兩種策略來消耗它發出的值:

流與異步管道相結合,如:

myTextSubscription$ = SomeObservable.subscribe();

{{ myTextSubscription$ | async }}

或者從訂閱處理程序中提取值並綁定它:

myTextSubscription$ = SomeObservable.subscribe(text => this.text = text);

{{ text }}

好吧,問題是我已經嘗試了幾次使用后一種方法,我從來沒有設法更新text值,除非我在處理程序中調用this.cdRef.markForCheck() 我想這種基本場景不應該需要手動調用changeDetection - 至少我沒有看到在任何截屏視頻或教程中使用過。

這聽起來對任何人都很熟悉嗎? 這是我對該方法的錯誤理解,還是Angular 2中的錯誤?


編輯:

上面的代碼已被抽象,因為我認為問題可以在更抽象的層面上解釋。

我不記得第一個案例,當它咬我,但現在Observable來自ngrx商店,所以它基本上是這樣的:

this.text$ = store.let((state$: Observable<State>) => {
  return state$.select(state => state.text);
});

如果SomeObservable以某種方式在Angulars區域之外初始化或使用某些未被zone.js轉換的API,則通常會發生這種情況。

我們需要看看SomeObservable是如何精確構建的,以確定無疑。

實際上,在使用async時不應訂閱observable。 這就是為什么async是那么棒的原因。 它在初始化/銷毀組件時處理subscribeunsubscribe

所以代替:
JS

myTextSubscription$ = SomeObservable.subscribe();

HTML

{{ myTextSubscription$ | async }}

你應該寧願:
JS

myTextSubscription$ = SomeObservable;

HTML

{{ myTextSubscription$ | async }}

我想澄清變量名中$的使用:
- 觀察值應以“$”為后綴
- 當你使用訂閱時,你沒有得到可觀察的

關於慣例:
JS

let someObservable$ = ...;

HTML

{{ someObservable$ | async }}

請記住:
- 當您使用訂閱時,您需要從observable 手動取消訂閱,但路由器和http除外)
- 當你有.subscribe ,返回的值是Subscription類型(這意味着你可以取消訂閱)

所以這里是一個更清潔的結構的概述(不使用異步管道):

@Component({
  selector: '...',
  templateUrl: '...html',
  styleUrls: ['...css']
})
export class AppComponent implements OnInit, OnDestroy {
    private myText: string;
    private myTextSubscription: Subscription;

    constructor() { }

    ngOnInit() {
        // I assume here that you declared an observable called "someObservable"

        this.myTextSubscription = someObservable$.subscribe(text => this.myText = text);
    }

    ngOnDestroy() {
        // as our observable is not coming from router or http, we need to manually
        // unsubscribe in order to avoid memory leaks

        this.myTextSubscription.unsubscribe();
    }

}

編輯1:使用您更新的示例,以下是如何將它與@ngrx一起使用:

@Component({
  selector: '...',
  templateUrl: '...html',
  styleUrls: ['...css']
})
export class AppComponent implements OnInit, OnDestroy {
  private text: string;
  private textSub: Subscription;

  constructor(private store$: Store<State>) {
    this.textSub =
        store$.select('yourState')
            .subscribe((state: State) => this.text = state);
  }

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM