Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Forms 基于Angular2模型的父/子表单_Forms_Typescript_Angular_Angular2 Forms - Fatal编程技术网

Forms 基于Angular2模型的父/子表单

Forms 基于Angular2模型的父/子表单,forms,typescript,angular,angular2-forms,Forms,Typescript,Angular,Angular2 Forms,我是Angular2(beta1)的新手,我想实现一种简单的可编辑网格,由两个组件组成。在这里,我使用两个伪数据组件来保持简单。他们是(看这本书:): 父组件,名为contact。假设它代表一个有名字的联系人 子组件,名为条目。假设它代表联系人的一个条目,其中每个联系人可以包含0个或多个条目。每个条目都有一个地址和邮政编码 我想创建一个表单,用户可以在其中编辑联系人的属性及其子条目:他可以添加新条目、删除现有条目或编辑现有条目 为此,这两个组件的视图都提供了一个基于表单的模板。 我可以想到这

我是Angular2(beta1)的新手,我想实现一种简单的可编辑网格,由两个组件组成。在这里,我使用两个伪数据组件来保持简单。他们是(看这本书:):

  • 父组件,名为
    contact
    。假设它代表一个有名字的联系人
  • 子组件,名为
    条目
    。假设它代表联系人的一个条目,其中每个联系人可以包含0个或多个条目。每个条目都有一个地址和邮政编码
我想创建一个表单,用户可以在其中编辑联系人的属性及其子条目:他可以添加新条目、删除现有条目或编辑现有条目

为此,这两个组件的视图都提供了一个基于表单的模板。 我可以想到这个数据流:

  • 联系人:用户编辑表单,然后单击提交按钮保存 整件事。因此,我可以使用一些代码来处理submit按钮 以及发出事件作为组件输出。联系人有一个
    条目
    数组属性:因此,我可以在其模板中使用
    ngFor
    指令进行渲染 它们中的每一个都有一个条目组件

  • 条目:条目具有表示
    控制组
    中包含的控制指令代表整个 形式。另外,我需要绑定几个属性作为 组件(
    address
    zip
    ),以便在父模板中执行以下操作:

    <tr *ngFor="#e of entries">
      <td><my-entry [address]="e.address" [zip]="e.zip"></my-entry></td>
    </tr>
    
    
    

  • 现在,我不清楚如何塑造表示控件输入的“model”属性和“form”属性之间的关系。我应该能够通过
    […]
    绑定从父组件获取地址和zip值,并通过子组件触发的事件(例如blur?)向上传递更新后的值。这在NG2世界有意义吗?无论如何,我在这里遗漏了一点:如何将表单控件值连接到模型属性值?有谁能说得更清楚些,或者指出一些好的文档吗?

    事实上,使用
    […]
    绑定只对应于单向绑定。在父零部件中更新父特性时,该值也会在子零部件中更新

    但如果要从子级更新父属性,则需要利用事件和
    @output
    属性

    下面是一个带有
    标签
    组件的示例:

    export class LabelsComponent implements OnInit {
      @Input()
      labels:string[];
    
      @Output()
      labelsChange: EventEmitter;
    
      (...)
    
      removeLabel(label:string) {
        var index = this.labels.indexOf(label, 0);
        if (index != undefined) {
          this.labels.splice(index, 1);
          this.labelsChange.emit(this.labels);
        }
      }
    
      addLabel(label:string) {
        this.labels.push(this.labelToAdd);
        this.labelsChange.emit(this.labels);
        this.labelToAdd = '';
        this.addAreaDisplayed = false;
      }
    }
    
    <labels [(labels)]="company.labels"></labels>
    
    通过这种方式,您可以在此组件上利用双向绑定:

    export class LabelsComponent implements OnInit {
      @Input()
      labels:string[];
    
      @Output()
      labelsChange: EventEmitter;
    
      (...)
    
      removeLabel(label:string) {
        var index = this.labels.indexOf(label, 0);
        if (index != undefined) {
          this.labels.splice(index, 1);
          this.labelsChange.emit(this.labels);
        }
      }
    
      addLabel(label:string) {
        this.labels.push(this.labelToAdd);
        this.labelsChange.emit(this.labels);
        this.labelToAdd = '';
        this.addAreaDisplayed = false;
      }
    }
    
    <labels [(labels)]="company.labels"></labels>
    
    
    
    希望它能回答你的问题,
    蒂埃里刚刚移动了评论以回答

    您可以传递对象e,而不是传递字符串。 i、 e

    
    

    然后在MyEntry组件中,对每个输入使用ng模型。因此,您会自动获得双向绑定。

    为什么不传递对象e,而不是传递字符串?即。然后在MyEntry组件中,对每个输入使用ng模型。所以你会自动得到双向绑定。谢谢你,我没有想过这个策略。我为对我感兴趣的读者制作了一个新的纪念品。请将您的评论作为回复发布,以便我将其标记为答案。谢谢@Naftis,我已经这样做了。如果需要,您可以使用plunker链接编辑答案。当您指定一个对象作为子组件输入属性的值时,我们不会“获得自动双向数据绑定”。发生的情况是,父组件和子组件现在都有一个属性,这两个属性都指向同一个/一个对象。它与角度双向数据绑定无关。这一切都与JavaScript引用类型有关。@MarkRajcok,我同意你的看法。对不起,我用错了词。这(将原语类型和/或对象绑定到范围)在Angular 1中已经解释过多次。我只是懒得再解释一遍整件事。