【问题标题】:Angular subscribe elegantAngular 订阅优雅
【发布时间】:2020-05-30 02:15:21
【问题描述】:

我想问一下我的订阅方法。我想从 firebase 获取我的对象(员工)并对我的对象进行大量操作,例如平均工资、平均缺勤天数……在我看来,这看起来太可怕了。我的服务无效:

 getEmployees(): Observable<Employee[]> {
    return this.db.list<Employee>(this.Api_url).snapshotChanges()
      .pipe(map(response => response.map(car => this.assignKey(car))));
  }

还有我的 ngOnInit:

  ngOnInit() {

    this.subscribtion = this.mainservice.getEmployees().subscribe((emps)=> {
      this.employees = emps;
      this.workersdatas = [];
      this.educationdatas = [];
      this.checkavaragesalaries(emps);
      this.countMonthAbsences(emps, 1);
      this.countMonthSalaries(emps, 1);
      this.departments.forEach((one)=> {
        const dep = emps.filter(on => on.department.includes(one) && this.FilterEmployees(on)).length;
        this.workersdatas.push({name: one, value: dep});
      });

      this.educations.forEach((one)=> {
        const edu = emps.filter(on => on.education.includes(one)).length;
        this.educationdatas.push({name: one, value: edu});
      });

      const mynumb =this.educationdatas.map(on => on.value);
      this.mosteducation = this.educationdatas.filter(one => one.value === Math.max(...mynumb))[0].name;
    }); }

我应该在 ngOnDestroy 上取消订阅()它还是没有必要?可以这样写吗?

【问题讨论】:

    标签: angular typescript rxjs


    【解决方案1】:

    我最喜欢的退订模式是使用takeUntiltakeUntil() 接受一个 observable,并在该 observable 发出一个值时停止订阅。

    冗长的方法是在ngOnDestroy() 中发出一个值。

    destroyed = new Subject<void>();
    
    ngOnInit(): void {
      myService.getData().pipe(
        takeUntil(this.destroyed)
      ).subscribe(data => {
        // process data
      });
    }
    
    ngOnDestroy(): void {
      this.destroyed.next();
      this.destroyed.complete();
    }
    

    一旦你这样做了几次,这就会变得相当乏味。我见过的最好的解决方案(和当前使用的)是设置一个共享函数,为你发出破坏的值。 SourceCredit

    import { OnDestroy } from '@angular/core';
    
    import { ReplaySubject, Subject, Observable } from 'rxjs';
    
    export function componentDestroyed(component: OnDestroy): Observable<void> {
      const oldNgOnDestroy: () => void = component.ngOnDestroy;
      const destroyed: Subject<void> = new ReplaySubject<void>(1);
      component.ngOnDestroy = () => {
        oldNgOnDestroy.apply(component);
        destroyed.next(undefined);
        destroyed.complete();
      };
      return destroyed.asObservable();
    }
    

    然后在您的组件中使用它几乎是微不足道的:

    ngOnInit(): void {
      myService.getData().pipe(
        takeUntil(componentDestroyed(this))
      ).subscribe(data => {
        // process data
      });
    }
    
    ngOnDestroy(): void {}
    
    

    您所要做的就是在您的组件中实现 ngOnDestroy 并将takeUntil(componentDestroyed(this)) 添加到您的管道中。

    【讨论】:

    • 我知道这个帖子有点老了,但是看看netbasal.com/automagically-unsubscribe-in-angular-4487e9853a88
    • @Eliseo 这是一个不错的选择。我不确定在发表这篇文章时我是否看过装饰者的方式。在这一点上,我认为这是一个偏好问题。我个人更喜欢直接调用函数的透明性,但我绝对可以理解为什么有些人更喜欢装饰器的“Automagic”。这里没有一个正确的答案:)
    【解决方案2】:

    是否允许像我一样将每个操作都放在 subscribe 方法中?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-11
      • 2021-04-21
      • 2016-10-09
      • 2018-04-19
      • 2021-11-18
      • 1970-01-01
      相关资源
      最近更新 更多