【问题标题】:Why isn't my input bound property changing in my angular child component?为什么我的输入绑定属性在我的 Angular 子组件中没有改变?
【发布时间】:2019-12-13 16:36:31
【问题描述】:

我有一个有两个孩子的父组件。

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

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);
}

这会打印0s,直到触发someFunctionInChildA,之后它会打印1s。

这是我的问题:孩子 B 似乎没有看到变化。这是孩子 B 的一些代码

@Input() dict: any;

ngAfterInit() {
  setInterval(() => console.log(this.dict), 1000);
}

这会一直打印0s,即使在someFunctionInChildA 已被触发之后。

我不明白属性绑定的工作原理吗?还是更有可能我在其他地方有一个愚蠢或不相关的错误?

【问题讨论】:

  • 如果您将间隔增加到 1500 毫秒,则在子 2 中...您看到 1 了吗?
  • 除了ngAfterInit 不是任何形式的生命周期钩子之外,我认为这没有任何理由不可行……但在角度上下文中这是非常糟糕的做法。远距离的对象突变导致非常难以理解的代码和难以理解的错误。这就是您可能遇到的情况
  • @Ramesh 更改间隔不会改变任何内容。我发现了这个错误,因为它破坏了预期的行为。 setInterval 只是用于调试。
  • @bryan60 感谢您的提示。我有一堆属性,它们都与在组件之间传递的一件事有关,所以我认为我会很聪明,并将它们全部放入字典中。对于我的用例,有没有更好的方法来做到这一点。也许如果我将该字典保存在服务中并且所有需要了解它的组件直接与它交谈?也许使用 setter 和 getter 代替?
  • 您应该使用服务和 rxjs 来共享对象并对其进行更改并通知其他组件

标签: angular typescript property-binding


【解决方案1】:

如您所见: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)
}

【讨论】:

  • 再次感谢您的额外说明。我现在已经回答了我自己的问题。原来我正在用 rxjs 做一些事情,但也留下了一些试图直接在组件内改变字典的逻辑。如果我更清楚你在这里展示的内容,我可能不会犯这个错误。
  • 是的,这些错误是您避免这种情况的原因。如果您练习此操作,应用程序会很快变得非常混乱
【解决方案2】:

我已经解决了这个问题,我怀疑其他人会发现这很有用,因为它很少发生......

几天前,我实际上做了一个服务,它将dict 保存并更新到 Firebase,这将通过 rxjs 与我的组件同步。但我留下了一些旧逻辑(即 dict 由组件而不是服务管理的逻辑)。

我会将其标记为正确答案,但真正要归功于 @bryan06,因为他对此类应用程序的正确模式进行了很好的解释。

【讨论】:

    猜你喜欢
    • 2020-01-30
    • 1970-01-01
    • 2018-10-31
    • 2018-05-15
    • 2021-03-12
    • 1970-01-01
    • 2022-01-06
    • 2018-10-31
    • 2020-08-05
    相关资源
    最近更新 更多