Angular 2反应形式问题

时间:2016-11-10 06:21:49

标签: angular angular-reactive-forms

我对Angular 2反应形式有疑问。我正在尝试在我的被动表单视图中做两件事:

  1. 在国家/地区名称的下拉列表中设置默认值。

  2. 根据国家/地区名称字段的选择更改国家/地区代码输入字段。见下面的html。

  3. country.ts

    export class Country {
      countryName: string;
      countryCode: number
    }
    

    in-memory-data.service.ts 这是我的数据库

    import { InMemoryDbService } from 'angular-in-memory-web-api';
    import { Injectable }    from '@angular/core';
    
    @Injectable()
    export class InMemoryDataService implements InMemoryDbService {`
    
       createDb() {
        let countries = [
          {
              countryName: 'Saudi Arabia',
              countryCode: '+966'
          }, {
              countryName: 'Bahrain',
              countryCode: '+973'
          }, {
              countryName: 'United Kingdom',
              countryCode: '+44'
          },{
              countryName: 'United Arab Emirates',
              countryCode: '+967'
          },{
              countryName: 'Brazil',
              countryCode: '+55'
          },{
              countryName: 'Czech Republic',
              countryCode: '+420'
          }
        ];
        return {countries};
      }
    }
    

    HTML

    <div class="container">
    
    <div class="row">
        <h1 id="header-1"> {{title}}</h1>
        <div id="instructions">
            <p>line 1 for description</p>
            <p>line 2 for description</p>
    
        </div>
    </div>
    
    <form class=" form form-inline" [formGroup]="userForm" novalidate>
        <div class="row from-inline" formArrayName="users">
            <div *ngFor="let user of userForm.controls.users.controls; let i=index">
                <div class="heading">
                    <span>{{i + 1}}.{{name}} </span>
                    <span class="glyphicon glyphicon-remove pull-right" *ngIf="userForm.controls.users.controls.length > 1"
                       (click)="removeDependent(i)"></span>
                </div>
                <div class="body" [formGroupName]="i">
                    <div class="row row-form-fields">
                        <div class="form-group col-xs-12 col-sm-6 col-lg-4">
                            <label class="sr-only" for="countryName">Country name</label>
                            <select class="form-control" id="countryName" formControlName="countryName" >
                                <option *ngFor="let country of countries" [ngValue]="country" >{{country.countryName}}</option>
                            </select>
                            <input type="text" class="form-control" formControlName="countryCode" id="countryCode"/>
                            <div [hidden]="userForm.controls.users.controls[i].controls.countryName.valid ||
                                      (userForm.controls.users.controls[i].controls.countryName.pristine && !submitted)" class="error-alert">
                           country is required
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <legend/>
        <div class="form-group">
            <div class="row user-form-btns">
                <div class="col-1-3">
                    <template ngbModalContainer/>
                    <dependent-modal-component/>
                </div>
                <div class="col-1-3">
                    <button class="btn btn-form" (click)="addDependentForm()">add dependents</button>
                </div>
                <div class="col-1-3">
                    <button type="submit" class="btn btn-form" id="btn-submit-form" (click)="onSubmit(userForm.value, userForm.valid)"
                        [disabled]="!userForm.valid">Submit</button>
                </div>
    
            </div>
        </div>
    </form>
    <div class="row">
        <pre>Is myForm valid?: <br>{{userForm.valid | json}}</pre>
            <pre>form value: <br>{{userForm.value | json}}</pre>
    </div>
    

1 个答案:

答案 0 :(得分:2)

如果要为控件设置默认值,可以在构建表单时执行此操作:

<强> FormBuilder

constructor(dataService: InMemoryDataService, private fb: FormBuilder) {
    this.name = 'Angular2';
    this.countries = dataService.createDb().countries;
    this.userForm = new FormGroup({
                       users: new FormArray([])
                    });

    let fg1 = new FormGroup({
      countryName: new FormControl(this.countries[0].countryName),
      countryCode: new FormControl(this.countries[0].countryCode)
    });

然后我们将订阅countryName控件上的更改以更新countryCode:

    fg1.controls.countryName.valueChanges.subscribe((countryName) => {
        fg1.controls.countryCode.setValue(this.findCountryCodeByCountryName(countryName));
    });
}

添加新用户:

addDependent() {
    let newGroup = new FormGroup({
          countryName: new FormControl(this.countries[0].countryName),
          countryCode: new FormControl(this.countries[0].countryCode)
        });

    newGroup.controls.countryName.valueChanges.subscribe((countryName) => {
      newGroup.controls.countryCode.setValue(this.findCountryCodeByCountryName(countryName));
    });

    this.userForm.controls.users.push(newGroup);
  }

HTML绑定将按照每个组进行:

<div class="body" [formGroupName]="i">
             <div class="row row-form-fields">
               <div class="form-group col-xs-12 col-sm-6 col-lg-4">
                 <label class="sr-only" for="countryName">Country name</label>
                 <select class="form-control" id="countryName" formControlName="countryName">
                   <option *ngFor="let country of countries" [ngValue]="country.countryName">{{country.countryName}}</option>
                 </select>
                 <input type="text" class="form-control" formControlName="countryCode" id="countryCode"/>
                 <div [hidden]="userForm.controls.users.controls[i].valid ||
                                (userForm.controls.users.controls[i].pristine && !submitted)" class="error-alert">
                     country is required
                     </div>
                 </div>
               </div>
            </div>

使用countryName绑定而不是绑定所选的输入国家会增加一些开销,我们必须在每次值更改时进行查找,而不是仅仅依赖我们已经存储的内容,但是这样做了。你想要的是什么。

这里是一名掠夺者:http://plnkr.co/edit/T7QcTcPKB1g7h0GbKYSu?p=preview