为什么我的有角子组件中的输入绑定属性没有更改?

时间:2019-12-13 16:36:31

标签: angular typescript property-binding

我有一个带两个孩子的父母。

父组件具有一个实际上像这样的字典的属性:

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

我不了解属性绑定的工作原理吗?还是我在其他地方有一个愚蠢或无关的错误?

3 个答案:

答案 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,他对此类应用程序的正确模式做了很好的解释。