繁体   English   中英

将可观察 object 的一部分作为 angular 组件的输入传递时出错?

[英]Error when passing part of an observable object as input to angular component?

我有一个关于我用我的 Observable 看到的种族案例的问题。 这可能更像是一个一般的可观察/角度问题。 从一条路线过渡到另一条路线时,我看到 controller 在我们过渡到新路线时正在破坏cannot read 'property' of undefined error 在我的 controller 中,我有这样的方法:

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

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

上面的 function 正在抛出错误。 在同一个组件模板中,我有:

<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>

我不喜欢这两种解决方案。 解决方案 AI 不喜欢,因为它在模板中看起来很笨重——但也许我应该处理它。 解决方案 BI 不喜欢,因为它不完全是一个优雅的解决方案。

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

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

利用

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

它会检查设置是否具有值并重用相同的 observable,每次访问 getter 时都无需重新创建 observable。

account$ 在组件被销毁之前发出 undefined ,这发生在您的路由选择器中,在组件被销毁之前的路由期间。

尝试

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$ 在组件被销毁之前发出 undefined 。

它仅在您从设置导航到主页时发生,这是您的路线选择器导致它发出未定义的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM