提问者:小点点

是否有等效的异步管道可以在组件中使用?


是否存在与async管道等效的东西,我可以在这样的组件中使用

   @Component({
      selector: 'my-component',
    })

    export class myComponent {

      myObservable$: Observable<string>;

      method() {
        doSomething(this.myObservable$);
        // here I would like to access directly the current string value of
        // myObservable$ without having to subscribe 
      }
    }

共3个答案

匿名用户

你必须问自己:你想通过避免订阅()调用来实现什么?我的猜测是,你想防止保留订阅并不得不手动取消订阅。

如果是这种情况,你只需要确保你得到一个完成的可观察对象。那么以后就不需要取消订阅了。你可以将任何可观察对象(有限或无限)转换为最终会完成的对象。

以下是您的案例示例:

  method() {
    this.myObservable$.take(1).subscribe(
      val => doSomething(val)
    );
  }

正确的方法实际上取决于你的可观察对象做什么以及你想用这个值做什么。例如,Angular2超文本传输协议调用自行完成,无需取消订阅!

或者,如果您想为可观察对象中的每个新值调用do东西,上述解决方案将不适合,因为您只获得第一个值,然后可观察对象就完成了。正如我所说,这归结为问题的上下文。

匿名用户

不存在。您需要手动订阅和手动取消订阅以避免内存泄漏。

对于一个简单的订阅,你可能会想做:

@Component({
  selector: 'my-component',
})
export class myComponent implements OnInit, OnDestroy {
  public myObservable$: Observable<string>;
  private myObservableSub: Subscription;

  ngOnInit() {
    this.myObservableSub = this
      .myObservable$
      .subscribe(_ => {
        // do something
      });
  }

  ngOnDestroy() {
    this.myObservableSub();
  }
}

但是如果你有很多订阅呢?你应该做这样的事情:

@Component({
  selector: 'my-component',
})
export class myComponent implements OnInit, OnDestroy {
  public myObservable1$: Observable<string>;
  private myObservableSub1: Subscription;

  public myObservable2$: Observable<string>;
  private myObservableSub2: Subscription;

  public myObservable3$: Observable<string>;
  private myObservableSub3: Subscription;

  ngOnInit() {
    this.myObservableSub1 = this
      .myObservable1$
      .subscribe(_ => {
        // do something
      });

    this.myObservableSub2 = this
      .myObservable2$
      .subscribe(_ => {
        // do something
      });

    this.myObservableSub3 = this
      .myObservable3$
      .subscribe(_ => {
        // do something
      });
  }

  ngOnDestroy() {
    this.myObservableSub1();
    this.myObservableSub2();
    this.myObservableSub3();
  }
}

更新回复(16/11/20)

在最初的答案中(见此编辑后),我确实使用了带直到,但这迫使您创建一个主题,并在组件被销毁时触发一个事件。虽然这背后的想法很好,但将我们订阅流的所有组件放入其中是相当多的样板。

取而代之的是,我们可以创建一个自定义运算符,我们可以将其称为带UntilDestroed并执行如下操作:

@Component({
  selector: 'my-component',
})
export class myComponent implements OnInit, OnDestroy {
  public myObservable1$: Observable<string>; // define your observable

  public myObservable2$: Observable<string>; // define your observable

  public myObservable3$: Observable<string>; // define your observable

  ngOnInit() {
    this
      .myObservable1$
      .pipe(takeUntilDestroyed(this))
      .subscribe(_ => {
        // do something
      });

    this.myObservableSub2 = this
      .myObservable2$
      .pipe(takeUntilDestroyed(this))
      .subscribe(_ => {
        // do something
      });

    this.myObservableSub3 = this
      .myObservable3$
      .pipe(takeUntilDestroyed(this))
      .subscribe(_ => {
        // do something
      });
  }

  ngOnDestroy() {}
}

这个自定义运算符的实现可以在这里找到:https://github.com/cloudnc/ngx-sub-form/blob/1115b21a007f72c54b521b3bed7c40051302145a/projects/ngx-sub-form/src/lib/shared/ngx-sub-form-utils.ts#L145-L148

原始答复

您应该执行以下操作:

@Component({
  selector: 'my-component',
})
export class myComponent implements OnInit, OnDestroy {
  private componentDestroyed$ = new Subject<void>();

  public myObservable1$: Observable<string>;
  public myObservable2$: Observable<string>;
  public myObservable3$: Observable<string>;

  ngOnInit() {
    this
      .myObservable1$
      .takeUntil(componentDestroyed$)
      .subscribe(_ => {
        // do something
      });

    this
      .myObservable2$
      .takeUntil(componentDestroyed$)
      .subscribe(_ => {
        // do something
      });

    this
      .myObservable3$
      .takeUntil(componentDestroyed$)
      .subscribe(_ => {
        // do something
      });
  }

  ngOnDestroy() {
    this.componentDestroyed$.next();
    this.componentDestroyed$.complete();
  }
}

如果你想了解更多,这里有一篇来自本·莱什的精彩文章:https://medium.com/@benlesh/rxjs-don-unscried-6753ed4fda87

编辑:
感谢@olsn,我编辑了我的答案并添加了带有next的行,因为确实一个完整的不会停止其他流。

我创建了一个小Plunkr来演示这种行为:https://plnkr.co/edit/dcueDqUgpqgYimxEAGUn?p=preview

匿名用户

如果您在Component或可以访问ChangeDetectorRef的东西中,您可以执行以下小技巧:

@Component({
...
  providers: [AsyncPipe]
})
export class ExampleComponent {
  app$ = this.sandbox.allApps$;
  apps = this.pipeAsync.transform(this.app$);

  contructor(
    protected pipeAsync: AsyncPipe,
    protected sandbox: AppAppsSandbox
  ) {}
}

这假设访问了一个名为AppAppsSandbox的服务,但Watableapp$可以来自任何地方,这是一种方便的解包方式。