【问题标题】:Angular 2 reactive forms issueAngular 2反应形式问题
【发布时间】:2016-11-10 06:21:49
【问题描述】:

我有一个关于 Angular 2 反应形式的问题。我正在尝试在我的反应式表单视图中做两件事:

  1. 在国家名称的下拉列表中有一个默认值。

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

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>

【问题讨论】:

    标签: angular angular-reactive-forms


    【解决方案1】:

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

    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

    【讨论】:

    • 你好,我想再补充一件事。我正在创建一个表单数组,表单组在其中。我不明白你为什么使用 (myForm.controls.countryName.valid) 而不是完整的东西 (userForm.controls.users.controls[i].controls.countryName.valid)。我编辑了我的问题以添加上面的整个 html
    • 更新了答案和 plunker 以解决您的问题。您在原始问题中没有明确提到 FormArray,因此没有得到解决。
    • 非常抱歉我的错误..非常感谢您的大力帮助
    • 感谢您提供的示例——这正是我需要了解自己的更新字段问题在哪里出错的原因。
    猜你喜欢
    • 2019-12-05
    • 2017-07-21
    • 2017-12-01
    • 2017-05-05
    • 2018-08-24
    • 1970-01-01
    • 1970-01-01
    • 2018-11-30
    • 2017-08-04
    相关资源
    最近更新 更多