【问题标题】:Angular (9) sharing common state between componentsAngular (9) 在组件之间共享公共状态
【发布时间】:2020-05-08 14:07:31
【问题描述】:

在当前 (2020) Angular 中,我有两个组件旨在通过服务共享 activeProject 的状态。我在ApplicationProjectService 上定义了以下内容:

private activeProjectSource = new BehaviorSubject(undefined);
activeProject$ = this.activeProjectSource.asObservable();

set activeProject(v: any) {
  this.activeProjectSource.next(v);
}

get activeProject() {
  return this.activeProjectSource.value;
}

我在服务中使用BehaviorSubject,因为我希望组件在订阅时获得当前值而不做任何更改。 getter/setter 在那里是因为我直接对服务属性进行了一些其他绑定,从那以后我不推荐使用它。

最终追溯到共同父级的两个同级组件,但我没有使用 @Input()@Output() 或在 DOM 中传递的任何参数:

this.appProjectService.activeProject$.subscribe(activeProject => {
  this.activeProject = activeProject;
});

每个组件都使用[(ngModel)] 绑定到各自组件中的this.activeProject 属性:

<input type="checkbox" [(ngModel)]="activeProject.someProperty">

问题

如果每个组件都获得了我认为是activeProjectthis.appProjectService.activeProject$.subscribe() 的副本,那么一个组件中本地属性的更改会反映在另一个组件中是如何工作的?最后这是我想要的行为,但我不明白为什么它会起作用。 rxjs observables 中是否有一些我不理解的引用传递?

【问题讨论】:

  • 我建议,访问这个 youtube 视频 youtube.com/… 您将确切了解如何在 angular 中使用主题
  • 我浏览了那个视频,它似乎与我从其他地方找到的内容相匹配,并且大部分都已实现。我认为我的问题不止于此,我想知道为什么我的代码在使用 Subject、Observable 和各种绑定时会执行它的功能。

标签: javascript angular typescript


【解决方案1】:

s如果您有 2 个组件,则两个局部变量 activeProject 使用相同的引用 activeProjectngModel 绑定到此引用的属性。所以它起作用了,因为组件中的更改只会更新引用的属性,而不会更改引用。您甚至可以使用变量activeProject,而无需将其包装在BehaviorSubject 中。

【讨论】:

  • 这是我最初的想法,但越想越觉得不对劲。局部变量没有直接引用activeProject 的服务实例,而是主题发出的变量,我假设它是两个不同的实例。这是否意味着 observables 发出对存储实例的引用而不是变量的值?
  • observable 发出值,但对象的值是它的引用。就像const c = {val: 1}; const a = c; const b = c; a.val = 2; console.log(b.val) // 2; console.log(c.val) // 2;
【解决方案2】:

我知道这应该在评论中,但这么多的信件评论不会接受。

暂时忘记RxJS

现在您的资产拥有gettersetter

您在服务中设置了activeProjectValue

现在,当您在一个组件中订阅它时,您将获得object,它将通过引用传递。其他组件也一样。由于两个组件都访问同一个对象,它们通过引用传递。

如果你必须打破引用,以不同的方式使用它。

还有each component obtained what I thought was a copy of activeProject .... 这意味着他们通过引用对象来复制。

我知道,你知道如何打破引用,但这只是为了未来的观众

要打破对象的引用,您可以使用JSON.parse(JSON.stringify(*ObjectName*)

在你的例子中

this.appProjectService.activeProject$.subscribe(activeProject => {
   this.activeProject = JSON.parse(JSON.stringify(activeProject));
});

【讨论】:

  • 感谢您的提示。我认为 observable 会改变主题对象的原始引用。在这种情况下,我似乎需要更多地考虑一下按值传递和按引用传递的细节。
猜你喜欢
  • 1970-01-01
  • 2019-01-31
  • 2017-05-06
  • 2019-02-18
  • 1970-01-01
  • 2016-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多