我有一个带两个孩子的父母。
父组件具有一个实际上像这样的字典的属性:
dict = {a: 0, b: 0, c: 0};
我进行输入绑定,以便两个子组件都可以访问dict
。
<app-child-a [dict]="dict"></app-child-a>
<app-child-b [dict]="dict"></app-child-b>
子级A更改属性dict
@Input() dict: any;
someFunctionInChildA() {
this.dict.b = 1;
}
我可以验证父组件是否知道此更改。
ngAfterInit() {
setInterval(() => console.log(this.dict), 1000);
}
这将打印0
直到触发someFunctionInChildA
,之后才打印1
。
这是我的问题:孩子B似乎看不到变化。这是孩子B的一些代码
@Input() dict: any;
ngAfterInit() {
setInterval(() => console.log(this.dict), 1000);
}
即使已触发0
,它也始终打印someFunctionInChildA
。
我不了解属性绑定的工作原理吗?还是我在其他地方有一个愚蠢或无关的错误?
答案 0 :(得分:2)
如您在此处看到的:https://stackblitz.com/edit/angular-7-master-nxys2f?file=src/app/hello.component.ts
有问题的代码可以正常工作。但是..这是非常糟糕的做法。因为这种远距离变异会导致难以推理的代码和难以理解的错误。我猜您的实际应用程序要复杂一些,并且您可能无意间破坏了参考。这就是为什么您应该使用共享服务模型和rxjs在组件之间共享信息的原因:
@Injectable()
export class DictService {
private dictSource = new BehaviorSubject({a: 0, b: 0, c: 0})
dict$ = this.dictSource.asObservable()
setDict(dict) {
this.dictSource.next(dict)
}
}
然后注入您的组件并订阅:
constructor(private dictService: DictService) {
this.dictSub = this.dictService.dict$.subscribe(dict => this.dict = dict) // don't forget to unsubscribe!
}
并使用该服务进行更新:
someFunctionInChildA() {
this.dict.b = 1;
this.dictService.setDict(this.dict)
}
答案 1 :(得分:0)
对象按值传递。当您传递对象(或数组)时,您(无形地)传递对该对象的引用。因此,当您在子组件中更改相同的值时,它指的是父对象Objet。如果您在子组件中更改对象引用,则该值将不会在父组件中更新
@Input() dict: any;
someFunctionInChildA() {
this.dict = {a:1};
}
答案 2 :(得分:0)
我已经弄清楚了这一点,我怀疑其他人会发现这很有用,因为这是一件罕见的事情……
几天前,我实际上提供了一项服务,该服务可以将dict
保存并更新到Firebase中,并且可以通过rxjs与我的组件同步。但是我留下了一些旧的逻辑(即dict
由组件而不是服务管理的逻辑)。
我将其标记为正确的答案,但真正的功劳归功于@ bryan06,他对此类应用程序的正确模式做了很好的解释。