Angular 订阅优雅 [英] Angular subscribe elegant

查看:26
本文介绍了Angular 订阅优雅的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'd like to ask about my subscribe method. I want to get my objects(employees) from firebase and do a loot of operations on my objects, like avg salaries, avg missed days... In my opinion it looks so horrible. My service void:

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

还有我的 ngOnInit:

And my 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 上取消订阅()还是没有必要?可以这样写吗?

Should I unsubscribe() it on ngOnDestroy or that's not necessary? Is that allowed to write it like that?

推荐答案

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

My favourite unsubscribe pattern is to use takeUntil. takeUntil() accepts an observable, and will stop the subscription when that observable emits a value.

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

The long-winded way to do this is emit a value in 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();
}

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

This gets quite tedious once you've done this a few times. The best solution I've seen for this (and currently use) is to set up a shared function that emits the destroyed value for you. Source Credit

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();
}

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

It is then almost trivial to use in your component:

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

ngOnDestroy(): void {}

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

All you have to do is implement ngOnDestroy in your component and add takeUntil(componentDestroyed(this)) to your pipe.

这篇关于Angular 订阅优雅的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆