【问题标题】:Angular - Why use 2-way binding instead of 1-way and modifying parent Input() directly?Angular - 为什么使用 2-way 绑定而不是 1-way 并直接修改父 Input()?
【发布时间】:2019-12-12 19:17:39
【问题描述】:

我对 Angular 还很陌生,希望有人能对此有所了解。

方法 1: 假设我使用 1 路数据绑定将父对象“x”传递给子组件:

<app-child [x]="x"></app-child>

我的子组件在 ts 中这样修改它:

Input() x;

然后:

this.x.someProperty = 'some new value';

这似乎工作正常,我在父级中的“x”对象已更新。

但是,在 Angular 教程和其他示例(例如 https://stackoverflow.com/a/41465022)中,执行此操作的“正确”方法似乎是 方法2:使用2路绑定例如:

<app-child [(x)]="x"></app-child>

在ts中

@Input() x: any;
@Output() xChange = new EventEmitter<any>();

然后:

this.x.someProperty = 'some new value';
this.xChange.emit(x);

我目前非常高兴地在 Angular 7 中使用方法 1,没有任何问题 - 谁能解释为什么(如果有的话)我应该改用方法 2?由于方法 1 有效,这似乎更复杂且不必要。

【问题讨论】:

  • 不应更新您的父属性。您是否将对象作为x 传递,然后对所述对象进行变异?
  • 您是否 100% 确定您的父组件中的值已更新?它不应该。除非您引用对象属性,否则在这种情况下,由于您引用了对象,更改属性 (this.x.someAttribute = 'some value') 也会在父组件中更改它。
  • 是的,你都是正确的 - x 实际上是一个对象 - 为了这个问题,我将它简化为一个字符串..
  • 已编辑问题并将 x 更改为对象

标签: angular angular7


【解决方案1】:

实际上这是一个非常好的问题,我也找不到任何官方解释为什么我们不应该改变 @input 的值,不像 reactJsvueJs,他们正式不鼓励我们改变 props .

除了@AJT82 所说的,原始值不能通过您的方法 1 更改。这是原因之一。我想另一个原因是,在 child 中改变 @input 值是不好的做法,它使代码更容易出错并且难以调试,它也打开了允许所有子组件任意更新对象的机会,这使我们很难追踪变化。

所以这更多是出于良好的开发实践原因,我们应该使用@output 来更新我们的父对象。

【讨论】:

    【解决方案2】:

    您正在使用一个对象,并且对象是通过引用传递的,并且是 mutable

    如果您要使用原始值,如 boolean,在您提供的链接中使用,那么修改子变量中的变量将不会反映在父变量中。您可以通过 demo 看到它,其中我们使用了一个字符串,这也是一个原语。为了实现该父级也将获得价值,您需要使用Output。选择使用双向绑定,即

    [(something)]="something" 
    

    与否,由你决定。您也可以使用单向绑定两种方式,例如:

    [something]="something" (somethingHasChanged)="parentFunction($event)" 
    

    所以双向绑定只是上述情况的简写。

    如前所述,对象(和数组)是可变的,因此请务必记住,如果您有时不想在父组件中反映您在子组件中所做的更改。

    【讨论】:

      猜你喜欢
      • 2019-04-03
      • 1970-01-01
      • 2015-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-22
      • 2011-07-30
      • 2019-02-20
      相关资源
      最近更新 更多