Angular 订阅优雅

Paw*_*ski -1 rxjs typescript angular

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

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

还有我的 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;
    }); }
Run Code Online (Sandbox Code Playgroud)

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

Kur*_*ton 8

我最喜欢的取消订阅模式是使用takeUntil. takeUntil()接受一个 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();
}
Run Code Online (Sandbox Code Playgroud)

一旦你这样做了几次,这就会变得非常乏味。我见过的最好的解决方案(目前正在使用)是设置一个共享函数,为您发出销毁的值。来源 信用

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();
}
Run Code Online (Sandbox Code Playgroud)

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

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

ngOnDestroy(): void {}

Run Code Online (Sandbox Code Playgroud)

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