【问题标题】:Why angular2 one-way binding between components works wrong with objects?为什么组件之间的angular2单向绑定对对象不起作用?
【发布时间】:2020-04-10 23:12:19
【问题描述】:

我有父组件和子组件。
我想将表单的值从父组件发送到子组件。
子组件可以使用这些数据做任何事情,但所有更改都是本地的,不应返回给父组件。

当我向子组件发送一个简单的变量时——一切正常,并且更改不会返回给父组件。
但是当我发送表单的值时 – 所有更改都返回到父组件...

直播

https://stackblitz.com/edit/angular-dvqyjr

父组件JS

export class AppComponent  {
constructor (private formBuilder: FormBuilder){};

simpleVariable = 'Value';
form: FormGroup = this.formBuilder.group({
    id: 1,
    name: 'Name'
});

父组件 HTML

<hello [simpleVariable]="simpleVariable" [form]="form.value"></hello>

子组件 JS

export class HelloComponent  {
  @Input() simpleVariable;
  @Input() form;
}

子组件 HTML

<input [(ngModel)]="simpleVariable">
<input [(ngModel)]="form.name">

问题

那么如何将对象发送到子组件并对其进行修改而不向父组件返回数据?

【问题讨论】:

    标签: javascript angular angular2-formbuilder


    【解决方案1】:

    这很简单。这种行为的原因是form.value 是一个对象。这意味着您正在与父母和孩子共享参考对象。这意味着对该对象的任何更改都会导致父级和子级都发生更改。

    为了在子组件中进行不会影响父组件的更改,请使用 Object.assign 函数创建对象的深层副本,并在子组件中使用它。

    export class HelloComponent implements OnInit {
      _from: {};
      @Input() simpleVariable;
      @Input() form;
    
      ngOnInit() {
        this._form = {};
        Object.assign(this._from, this.form);
      }
    }
    

    Forked and edited example

    【讨论】:

    • 谢谢!那么如何在不向父组件返回数据的情况下将对象发送到子组件并对其进行修改?
    • @Tison 您可以使用Object.assign 函数创建对象的深层副本,并在您的子组件中使用它。
    • 我试过了,但没有结果...stackblitz.com/edit/…
    • 非常感谢!但我认为这种行为是不正确的......我认为当我希望将更改从孩子反映回父母时,我会使用双向绑定 [(foo)]="foo"
    • @Tison 您的想法是正确的,但它只是使用值类型的方式。如您所见,对于引用类型,它是不同的。
    【解决方案2】:

    来自Reactive Forms - Step 2: Associating the FormGroup model and view 的 Angular 文档:

    表单组跟踪其每个控件的状态和更改,因此如果其中一个控件发生更改,父控件也会发出新的状态或值更改。

    【讨论】:

      【解决方案3】:

      你可以试试下面的表格:

      <form [formGroup]="form">
        <input formControlName="name">
      </form>
      

      【讨论】:

        【解决方案4】:

        这一切都归于Explaining Value vs. Reference in Javascript 以及Angular's Change Detection

        总的来说,@benshabatnoam 已经回答了您的问题 - 为了执行更改检测 - 您需要通过老式方式更改对象引用:

        Object.assign(this._from, this.form);
        

        或者ES6方式:

        this._from = {...this.form}
        

        【讨论】:

          猜你喜欢
          • 2012-01-19
          • 2017-03-15
          • 1970-01-01
          • 2017-02-06
          • 1970-01-01
          • 2016-09-28
          • 2021-04-30
          • 2018-05-03
          • 1970-01-01
          相关资源
          最近更新 更多