簡體   English   中英

Angular 自動完成哪些 observables?

[英]Which observables do Angular complete automatically?

Angular產生的哪些observables也由Angular完成?

例如:

  • HttpClient在請求完成時完成所有 observables
  • 當路由改變時,來自Router的 observables(parammap、queryparammap 等)會自動完成。

Angular 中的哪些其他可觀察值Angular會在什么情況下自動為您完成?

當路由改變時,來自路由器的 observables [...] 會自動完成。

我不會說這是真的。 當路由更改時,該視圖被銷毀,並且由於每個ActivatedRoute都與一個路由相關聯(因此與一個路由組件相關聯),當該組件被銷毀時,其中的所有內容都將被銷毀,以及對屬於該組件的源的任何訂閱(例如ActivatedRoute.params )。 至少這是我注意到的,但是當路由更改時,它肯定不會發出完整的通知。

這同樣適用於@ViewChildren 由於它會從當前組件的視圖中查詢元素,當組件被銷毀時,該源( @ViewChildren.changes )也將被清空,因此無需手動取消訂閱。

valueChangesstatusChanges相同(假設表單控件是在該組件中創建的)。

例如,當您擁有全局服務時,可能會發生 Memory 泄漏。 因為它是全局的,所以它只保留對訂閱者的引用,訂閱者可以來自多個地方。 但是由於全局服務的存在不依賴於組件是否被銷毀,所以由該組件讓服務知道它不再對接收值感興趣。


守衛會發生一些非常有趣的事情。

當使用canLoad守衛時,如果你返回一個 observable,你必須確保你的 observable 完成(例如通過添加take(1) )。 這很重要,因為 Angular不會自動為您處理:

sbj = new BehaviorSubject(true)

canLoad (route: Route, segments: UrlSegment[]) {
  // Although it's returning `true`, it never completes
  return this.sbj;
}

它的實現我們可以看出原因:


// Observable that will emit each `canLoad` individually
const obs = from(canLoad).pipe(map((injectionToken: any) => {
  const guard = moduleInjector.get(injectionToken);
  let guardVal;
  if (isCanLoad(guard)) {
    guardVal = guard.canLoad(route, segments);
  } /* ... */
  return wrapIntoObservable(guardVal);
}));

return obs.pipe(
  // `concatAll` === `mergeMap(obs => obs, 1)`
  // `concatAll` requires an observable to **complete** in order to subscribe to the next one
  concatAll(),
  /* ... */
  every(result => result === true),
);

另一方面,例如使用canActivate時,情況就不同了。 這一次,Angular 將自動取第一個值然后完成,所以這應該工作:

sbj = new BehaviorSubject(true);

canActivate(
  next: ActivatedRouteSnapshot,
  state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {

  return this.sbj;
}

實施中所見:

const canActivateObservables = canActivate.map((c: any) => {
  return defer(() => {
    const guard = getToken(c, futureARS, moduleInjector);
    let observable;

    if (isCanActivate(guard)) {
      observable = wrapIntoObservable(guard.canActivate(futureARS, futureRSS));
    } /* ... */

    // Only get the first emitted value and then complete
    return observable.pipe(first());
  });
});
return of(canActivateObservables).pipe(prioritizedGuardValue());

異步 pipe 訂閱 Observable 或 Promise 並返回它發出的最新值。 當發出新值時,異步 pipe 標記要檢查更改的組件。 當組件被銷毀時,異步 pipe 會自動取消訂閱以避免潛在的 memory 泄漏。

(來自https://angular.io/api/common/AsyncPipe

暫無
暫無

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

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