从组件类中的 observable 中获取唯一/最新值(商店选择器的结果)

bub*_*ble 5 ngrx angular

我的应用程序正在使用 Angular 和 ngrx 商店。我在商店中使用选择器来获取组件构造函数中应用程序状态的用户名属性:

测试组件.ts

export class TestComponent {
    username$: Observable<string>;
    constructor(private store: Store<fromRoot.AppState>) {
        this.username$ = this.store.select(fromRegistration.getUsername);
    }

    testMethod() {
         //I need the value of the username observable here as a string
    }

}
Run Code Online (Sandbox Code Playgroud)

这工作正常。我需要在组件的模板中打印用户名,这是我使用异步管道完成的:

测试组件.html

<div>
{{username | async}}
</div>
Run Code Online (Sandbox Code Playgroud)

这也正常工作。

现在,我需要从 TestComponent 中的一个方法调用一个服务,该方法将用户名作为参数发送。我怎样才能做到这一点?我是否需要停止使用异步管道并订阅选择器,然后将 username 属性(然后将其声明为字符串)分配给 observable 的值?

注意:用户名 observable 只有 1 个值,一旦我得到 1 个值,我就可以停止观看它。

我知道通过使用异步管道组件会自动从用户名 observable 取消订阅,这什么时候发生,组件如何知道我不再需要观看它?

如果我不能使用异步管道,我应该如何以及何时取消订阅?

Sal*_*ani 3

我通常会选择 Maciej Treder 的第一个想法,因为我会尽可能地尝试使用哑组件,但在某些情况下,当我需要选择器中的新值来在组件内执行额外的操作时,我会将其异步通过管道传输到我的模板无论如何(所以我不需要任何订阅),我只需使用 rxjs tap运算符,它是do的可管道运算符名称。所以我替换这个:

ngOnInit() {
  this.selected$ = this.store.pipe(select(fromItems.getSelectedBrand));
}
Run Code Online (Sandbox Code Playgroud)

这样:

import { Store, select } from '@ngrx/store';
import { tap } from 'rxjs/operators';

...

ngOnInit() {
  this.selected$ = this.store.pipe(
    select(fromItems.getSelectedBrand),
    tap((brand: Brand) => {
      /**
       * do logic here
       */
    })
  );
}
Run Code Online (Sandbox Code Playgroud)

现在,如果由于某些原因您确实需要订阅它而不需要像Maciej Treder 的第二个解决方案中那样将其异步管道传输到任何模板,我建议使用ngOnDestroy取消订阅。您可以在这里找到更多相关信息: