(Angular)从子级销毁父级订阅

Posted

技术标签:

【中文标题】(Angular)从子级销毁父级订阅【英文标题】:(Angular) Destroying parent subscriptions from child 【发布时间】:2022-01-18 02:27:48 【问题描述】:

//父组件

subscription: Subscription[] = [];

//stuff

constructor(private http: HttpService, private route: ActivatedRoute) 

  const subLoading = this.http.loading.subscribe((loading: boolean) => 
    this.loading = loading;
  );

//stuff to do

   this.subscription.push(subLoading);
   this.subscription.push(subData);


ngOnDestroy() 
  console.log("logged if logging out directly from here")
  this.subscription.forEach((sub) => 
    sub.unsubscribe();
  );

//子组件

与从孩子到父母的路线相关联 (父 URL : domain/list , eg.: Child URL: domain/list/item/53 )

//应用路由

const routes: Routes = [
   path: '', component: AuthComponent ,
   path: 'list/:pageID', component: ListComponent, canActivate: [AuthGuard] ,
  
    path: 'list/item/:id',
    component: ListItemDetailComponent,
    canActivate: [AuthGuard],
  ,
];

//标题

    export class HeaderComponent implements OnInit 
  public isLoggedIn = false;
  private userSub: Subscription;

  constructor(private authService: AuthService) 

  ngOnInit(): void 
    this.userSub = this.authService.user.subscribe((user) => 
      this.isLoggedIn = !!user ? true : false;
    );
  

  ngOnDestroy(): void 
    this.userSub.unsubscribe();
  

  logOut() 
    this.authService.logOut();
  

标题中我取消订阅,销毁用户(BehaviourSubject)并注销

但是我在父组件中订阅的许多 BehaviourSubjects如果我在子组件中退出时不会被销毁

有什么办法吗?

【问题讨论】:

您能否提供您的代码的全貌。 我添加了一堆,希望它仍然可以遵循,你对这个问题有什么想法吗?或者我可以通过其他方式取消订阅父组件中的订阅? 如果列表组件路由仍然活跃,组件不会被销毁。如果您想注销并留在列表组件中,那么您可以使用 authService 通知您的所有组件有关注销并取消订阅特定订阅。否则,如果您导航到特定于注销的路线,那么您的列表组件将被销毁,并且取消订阅将被调用 onDestroy。 尝试使用类似:destroyed$ = new Subject(); ngOnDestroy() this.destroyed$.next(true); this.http.loading.pipe(takeUntil(this.destroyed$)).subscribe((loading) => );。这样你就不需要管理那些烦人的订阅了 @MehyarSawas “如果您导航到注销特定路线,那么您的列表组件将被销毁”您是什么意思?以某种方式创建注销路由? 【参考方案1】:

只是一点,你不会破坏 BehaviourSubjects ,你会破坏订阅,这就是为什么其他订阅了相同 behaviorSubject 的组件会保留它们的订阅。 我认为您可以在注销时使用其他主题发出,并在每个订阅中使用它,使用 takeUntil() 运算符。 (takeUntil rxjs operator examples)

更新: 认证服务:

logoutSubject = new Subject(); // 
logout$ = this.logoutSubject.asObservable();  

在您想要订阅用户直到注销的任何组件中

this.authService.user
.pipe(takeUntil(this.authService.logout$)) // it will managing subscription until logout observable emit
.subscribe((user) => 
      this.isLoggedIn = !!user ? true : false;
    );

我认为这应该可以解决您的问题,但请注意,如果您再次尝试登录,该订阅将无法正常工作,因为已终止。

【讨论】:

“注销时使用其他主题发出”你能详细说明一下吗?我可以在注销时使用什么其他主题?这与我在父组件中订阅的那些有什么关系

以上是关于(Angular)从子级销毁父级订阅的主要内容,如果未能解决你的问题,请参考以下文章

Angular 孩子与父母的互动

Angular 中的子父级沟通最佳实践

Angular 组件在被销毁后仍在监听订阅 [重复]

从父级访问 Angular 1.x 组件属性

markdown Angular - 从父级调用子组件函数

当父组件使用 ng-content Angular 时从子组件访问父组件