1

我正在尝试创建我的第一个 Angular 2 应用程序。和往常一样,我立即遇到了我想要创建的模型的麻烦。我有一个用于在 artilces 之间创建父子关系的模型。例如:我想在我的购物篮中添加一篇文章,其中包含一些子对象,如下所示:

IArticle[] = [
{
    id: 1,
    parentArticle: 1234596,
    description: 'some description for parent'
    children: [
        {
            id: 1,
            childArticle: 123457,
            childDescription: 'some description for first child'
        },
        {
            id: 2,
            childArticle: 123467,
            childDescription: 'some description for second child'
        },
        .....
    ]

在打字稿中,我为我的文章定义了一个接口。子对象有自己的界面,但略有不同。

因为这些子对象是一个小的固定集,所以我想使用下拉列表添加这些子对象。我希望这些对象在单击时显示为带有移除的按钮(可选的模式弹出窗口带有“你确定”问题)。所以我认为下拉列表旁边的按钮应该将下拉列表值添加到数组中。当我将值添加到普通类型的数组时,这工作正常。但现在我想把这个数组包装成一个“反应形式”。

有人可以帮助我如何在这些反应式表单中使用数组以及如何将它们包装在 formcontrol 对象中。我查看了 FormArray“控件”,但不确定这是否是我正在寻找的。它缝合了一个 FormControls 数组,而不是一个数据数组。也许 Reactive Forms 不是正确的决定?希望有人能让我走上正轨。

我的html模板如下(从代码中剥离的引导代码)

<form autocomplete="off">
      <input type="text" Placeholder="Article Number" />
    <div >
      <button *ngFor="let child of children">
        <span class="glyphicon glyphicon-remove-circle text-danger"></span>
        {{ child.childArticle }}
      </button>
    </div>
    <div >
        <select class="form-control inline">
          <option value="">Select Service..</option>
          <option *ngFor="let serviceOption of serviceOptions" [ngValue]="serviceOption.serviceNumber">
              {{serviceOption.serviceDescription}} 
          </option>
        </select>
          <button  (click)="onAddService()">
             Add
          </button>
    </div>
    <div>
      <button type="submit">
         Save
      </button>
    </div>
  </form>

亲切的问候。

------ 打字稿代码:

export class NewServiceComponent implements OnInit {
  newServiceForm: FormGroup;
  serviceOptions: IServiceArticle[] = [
     { 'id': 1, 'serviceNumber': 123456, serviceDescription: 'description 1' },
     { 'id': 2, 'serviceNumber': 456789, serviceDescription: 'description 2' },
     { 'id': 3, 'serviceNumber': 123456, serviceDescription: 'description 3' },
];
selectedServiceOption: IServiceArticle;
newArticle: IService;

constructor(private _fb: FormBuilder) {
}

createForm() {
 this.newServiceForm = this._fb.group({
   services: this._fb.array([]),
   articleNumber: this._fb.control(null, Validators.required),
 })
}

ngOnInit() {
  this.createForm();
}

onAddService() {
  const arrayControl = <FormArray>this.newServiceForm.controls['services'];
  let newgroup = this._fb.group({
    serviceNumber: this.selectedServiceOption.serviceNumber,
    serviceDescription: this.selectedServiceOption.serviceDescription,
  })
  arrayControl.push(newgroup);
}
}
4

2 回答 2

0

尝试了以下代码,它似乎可以正常工作......

至于表单,您需要添加[formGroup],所以:

<form [formGroup]="newServiceForm">

并且由于它现在在表单组内,因此它不会接受没有表单控件[(ngModel)]的情况。select我们可以绕过这个使用[ngModelOptions]="{standalone: true}"

我也将更[ngValue]改为引用对象:[ngValue]="serviceOption"

然后我们添加选定的值并将其推送到表单数组,就像您所做的那样。

在模板中,我们现在要迭代这个表单数组。总而言之,模板应该是这样的:

<form [formGroup]="newServiceForm">
  <div formArrayName="services">
    <button *ngFor="let child of newServiceForm.controls.services.controls; 
         let i = index" [formGroupName]="i">
      <span [innerHtml]="child.controls.serviceDescription.value"> </span>
    </button>
  </div>

 <select [(ngModel)]="selectedServiceOption" [ngModelOptions]="{standalone: true}">
    <option>Select Service..</option>
    <option *ngFor="let serviceOption of serviceOptions" [ngValue]="serviceOption">
          {{serviceOption.serviceDescription}} 
    </option>
 </select>
 <button  (click)="onAddService()"> Add </button>
</form>

表单控件也可以设置为变量,这样您就可以避免那些长路径。

正如评论中所讨论的,这没有考虑到用户可以一遍又一遍地选择相同值的事实,但这与问题无关。

于 2017-07-18T13:21:09.480 回答
0

创建响应式表单时,您首先拥有主表单组,并且您将在表单组内拥有一个 formArray 控件。完成此操作后,您将向该 formArray 添加任何现有子项,并且每个子项都将成为其自己的 formGroup。

constructor(private fb: FormBuilder){
    myTypeScriptChildrenObjects = functionToGetTheChildrenArray();
}
...

createForm(){
    this.form = this.fb.group({
        childrenArray: this.fb.array([])
    })

    const arrayControl = <FormArray>this.orderForm.controls['childrenArray'];
    this.myTypeScriptChildrenObjects.forEach(item => {
        let newGroup = this.fb.group({
            prop1: [item.prop1],
            prop2: [item.prop2],
            prop3: [item.prop3]
        })
        arrayControl.push(newGroup);
    })
}

在您的 html 中循环浏览这些内容时,您可以执行以下操作:

<select formArrayName="childrenArray">
          <option [formGroupName]="i" *ngFor="let line of form.controls['childrenArray'].controls; index as i" text="prop1" value="prop2">
于 2017-07-17T21:29:42.753 回答