Проблема с реактивными формами Angular 2

У меня вопрос по реактивным формам 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>

person Mish    schedule 10.11.2016    source источник


Ответы (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? >

person silentsod    schedule 10.11.2016
comment
привет, я хочу добавить еще кое-что. Я создаю массив форм, а группа форм находится внутри него. Я не понял, почему вы использовали (myForm.controls.countryName.valid) вместо полной версии (userForm.controls.users.controls [i] .controls.countryName.valid). Я отредактировал свой вопрос, чтобы добавить весь html выше - person Mish; 12.11.2016
comment
Обновленный ответ и плункер для решения ваших проблем. У вас вообще не было FormArray, прямо упомянутого в вашем исходном вопросе, поэтому он не был рассмотрен. - person silentsod; 15.11.2016
comment
очень сожалею об этой моей ошибке .. очень признателен вам за большую помощь - person Mish; 15.11.2016
comment
Спасибо за пример - это было именно то, что мне нужно, чтобы увидеть, где я ошибся с моей собственной проблемой update-a-field. - person Connie H.; 26.04.2019