Angular订阅优雅 [英] Angular subscribe elegant

查看:51
本文介绍了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()接受一个可观察对象,并在该可观察对象发出值时停止订阅.

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天全站免登陆