将可观察对象的一部分作为角度分量的输入时出错?

时间:2019-11-01 23:39:28

标签: javascript angular rxjs observable ngxs

我对我的Observable看到的竞赛案例有疑问。这可能更像是一个一般的可观察/角度问题。从一条路线过渡到另一条路线时,我看到一个cannot read 'property' of undefined error在控制器上正在销毁,因为我们过渡到一条新路线。在我的控制器中,我有一个像这样的方法:

// this.setting$: Observable<object>;

get name$: Observable<string> {
    return this.settings$.pipe(map(settings => settings.name));
}

上面的函数抛出错误。 在相同的组件模板中,我得到了:

<some-component [name]="name$ | async"></some-component>

当我切换到新页面时,this.settings$选择器将返回undefined,并且我的控制器的代码将引发错误。奇怪的是,发生控制台错误时(通过控制台日志记录ngOnDestroy进行了测试),我的组件已经被破坏。

我找到了两种解决问题的解决方案。解决方案A:

// Parse the name property in the template - which I think looks ugly
<some-component [name]="(settings$ | async).name"></some-component>

或者,解决方案B:

// Pass entire settings object into component and parse out name in some-component controller - yuck
<some-component [settings]="settings$ | async"></some-component>

我不喜欢任何一种解决方案。解决方案A我不喜欢,因为它在模板中看起来很笨拙-但也许我应该处理它。解决方案B我不喜欢,因为它不是一个完美的解决方案。

我不太明白为什么两种解决方案都能解决问题。任何人都可以指出为什么存在此问题吗?特别是考虑到组件已被破坏。感觉像是一个孤立的订阅,但我不知道如何。

编辑:我创建了一个重现该问题的stackblitz。 https://stackblitz.com/edit/ngxs-repro-ndaco6。一共有三种路由:/ home,/ profile,/ settings。 / profile和/ settings取决于URL中的帐户ID。 / home没有。从/ profile到/ home路由时,请注意没有控制台错误。但是,当您从/ settings路由到/ home时,会出现控制台错误。有人可以帮我理解为什么吗?请注意,引发错误时,引发错误的SettingsComponent已被破坏。

2 个答案:

答案 0 :(得分:1)

使用

name$ = this.settings$.pipe(map(settings => settings ? settings.name : null));

它会检查设置是否具有值并重复使用相同的可观察对象,而无需在每次访问getter时都重新创建可观察对象。

答案 1 :(得分:0)

account $在销毁组件之前发出不确定的消息,这是在销毁组件之前在路由选择器中发生的情况。

尝试

age$ = this.account$.pipe(
  tap(val => {
    console.log('Account obs val is', val);
  }),
  map(account => account.age)
);

https://stackblitz.com/edit/ngxs-repro-ceetsi?file=src/app/components/settings.component.ts

您可以看到在销毁组件之前account $会发出未定义的消息。

只有当您从设置导航到主页时,它才会发生,它是您的路由选择器,导致其未定义发出。