如何在 HTML 中迭代和引用控制组的数组



在 Angular 2 中,如何迭代 ControlGroup 数组并引用组中的控件?

ControlGroup 和 ControlArray plnkr 示例创建一个(空)城市Control数组:

ctrlCities: Control[] = [
    new Control(''),
    new Control(''),
    new Control('')
];

将它们包裹在ControlArray中:

citiesArray: ControlArray = new ControlArray(this.ctrlCities);

并将它们分配给ControlGroup形式,citites

formGroup: ControlGroup = new ControlGroup({
    name: new ControlGroup({
        first: this.ctrlFirst,
        middle: this.ctrlMiddle,
        last: this.ctrlLast
    }),
    food: this.ctrlFood,
    cities: this.citiesArray
});

然后 HTML 迭代表单ControlGroup

<form [ng-form-model]="formGroup">

cities ControlGroup

    <ul ng-control-group="cities">

最后处理 Control 数组中的每个Control

      <li *ng-for="#ctrl of ctrlCities; #i = index"><input ng-control="{{i}}"></li>

如果城市控制器是一个组,我将如何引用该组中的控制?

大概,我会补充

ngControlGroup="{{i}}"
到我的块

,然后在该块中引用组的各个控件,但这会导致我的应用程序中出现以下情况:

angular2.dev.js:23597 Error: Cannot find control '0'
    at new BaseException (angular2.dev.js:7464)
    at _throwError (angular2.dev.js:20733)
    at Object.setUpControlGroup (angular2.dev.js:20726)
    at NgFormModel.addControlGroup (angular2.dev.js:16863)
    at NgControlGroup.ngOnInit (angular2.dev.js:16708)
    at AbstractChangeDetector.ChangeDetector_MarketplaceAddComponent_7.detectChangesInRecordsInternal (viewFactory_MarketplaceAddComponent:2800)
    at AbstractChangeDetector.detectChangesInRecords (angular2.dev.js:8156)
    at AbstractChangeDetector.runDetectChanges (angular2.dev.js:8139)
    at AbstractChangeDetector._detectChangesContentChildren (angular2.dev.js:8212)
    at AbstractChangeDetector.runDetectChanges (angular2.dev.js:8140)

任何想法如何做到这一点?

旁白:控制 API 有点笨拙:在控制器中,新的ControlpushControlArraycitiesArray ),但在视图中,我们迭代了 Control 的数组 ( ctrlCities )。为什么不是一个或另一个?

这是带有

解决方案的更新 plnkr; 控制器被修改为使用具有namesize控件的每个城市的组:

ctrlCities: ControlGroup[] = [
    new ControlGroup({'name':new Control(''),'size':new Control('')}),
    new ControlGroup({'name':new Control(''),'size':new Control('')}),
    new ControlGroup({'name':new Control(''),'size':new Control('')})
];

视图集组在div数组中,然后直接引用namesize

    <ul ng-control-group="cities">
      <li *ng-for="#ctrl of ctrlCities; #i = index">
      <div ng-control-group="{{i}}">
        <input ng-control="name"> <input ng-control="size">
      </div>
      </li>
    </ul>

我在使用@angular2-material和ng2-material时遇到了同样的问题,以便利用md-messages(来自ng2-material)的使用,并能够通过编写更少的html代码自动显示错误。

在浪费了几个小时之后,我终于明白了如何将 ControlArray 与 ControlGroup 一起使用。

启发了自己以下的 plunkr: http://plnkr.co/edit/23DESOpbNnBpBHZt1BR4?p=preview

要理解的关键点是,您始终需要在表单构建器定义中定义的控制组中嵌套字段,即使它是控制数组。

我做了一个plunkr来展示如何使用它:http://plnkr.co/edit/QX6mjoVNd7ZopsGzmKk7

//our root app component
import {Component} from "@angular/core";
import {
  Control,
  ControlGroup,
  ControlArray,
  FORM_DIRECTIVES,
  FormBuilder,
  Validators
} from '@angular/common';
import {MATERIAL_DIRECTIVES} from "ng2-material/index";
import {MD_INPUT_DIRECTIVES} from "@angular2-material/input";
@Component({
  selector: 'my-app',
  providers: [],
  directives: [MATERIAL_DIRECTIVES, MD_INPUT_DIRECTIVES]
  template: `
  <md-card>
    <form name="setProfileForm" [ngFormModel]="setProfileForm">
      <md-card-content>
        <h2>Curriculum vitae</h2>
        <div ngControlGroup="profileInfos">
          <h3>About you</h3>
          <div class="md-input-container">
            <md-input #firstName="ngForm" ngControl="firstName" type="text" placeholder="Firstname"></md-input>
            <div [md-messages]="firstName" role="alert">
              <div md-message="required">Please provide a Firstname!</div>
            </div>
          </div>
          <div class="md-input-container">
            <md-input #lastName="ngForm" ngControl="lastName" type="text" placeholder="Lastname"></md-input>
            <div [md-messages]="lastName" role="alert">
              <div md-message="required">Please provide a Lastname!</div>
            </div>
          </div>
          <div ngControlGroup="positions">
            <h3>Your job positions</h3>
            <div *ngFor="let controlGroup of positionsControlGroup; let i = index" ngControlGroup="{{i}}">
              <h4>Position #{{i+1}}</h4>
              <div class="md-input-container">
                <md-input #company="ngForm" ngControl="company" type="text" placeholder="Company"></md-input>
                <div [md-messages]="company" role="alert">
                  <div md-message="required">Please provide a Company!</div>
                </div>
              </div>
              <div class="md-input-container">
                <md-input #title="ngForm" ngControl="title" type="text" placeholder="Title"></md-input>
                <div [md-messages]="title" role="alert">
                  <div md-message="required">Please provide a Title!</div>
                </div>
              </div>
            </div>
          </div>
        </div>
        <md-card-actions>
          <button type="submit" md-button md-raised-button class="md-primary" [disabled]="!setProfileForm.valid">Submit</button>
        </md-card-actions>
      </md-card-content>
    </form>
  </md-card>
  `
})
export class App {
  setProfileForm:ControlGroup;
  positionsControlGroup:ControlGroup[];
  positionsControlArray:ControlArray;
  constructor(public fb: FormBuilder) {
    this.positionsControlGroup = [
      fb.group({
        company: fb.control(null, Validators.required),
        title: fb.control(null, Validators.required)
      }),
      fb.group({
        company: fb.control(null, Validators.required),
        title: fb.control(null, Validators.required)
      })
    ];
    this.positionsControlArray = fb.array(this.positionsControlGroup);
    this.setProfileForm = fb.group({
      profileInfos: fb.group({
        firstName: fb.control(null, Validators.required),
        lastName: fb.control(null, Validators.required),
        positions: this.positionsControlArray
      })
    });
  }
}

最新更新