что означает formarray.controls в форм-массиве в угловых 5? - PullRequest
0 голосов
/ 03 мая 2018

Я новичок в angular 5, поэтому в основном все еще цепляюсь за концепции. На примере документации Angular по реактивным формам (https://angular.io/guide/reactive-forms), следующий код такой:

<div formArrayName="secretLairs" class="well well-lg">
<div *ngFor="let address of secretLairs.controls; let i=index" 
 [formGroupName]="i" >
    <!-- The repeated address template -->
  </div>
  </div>

Что означает secretlairs.controls и что это? По угловой это означает, что:

Источником повторяющихся элементов является FormArray.controls, а не сам FormArray. Каждый элемент управления является адресом FormGroup, именно таким, как ожидал предыдущий (теперь повторенный) шаблон HTML.

Есть ли в secretlairs.controls какие-либо данные? Могу ли я заменить эту часть на, скажем, сам объект данными любого типа и создать экземпляр данных, полученных из webapi? Например, вместо

*ngFor="let address of secretLairs.controls

я использую

*ngFor="let address of addresses

где адреса имеют тип any и данные получены из базы данных.

1 Ответ

0 голосов
/ 03 мая 2018

Во-первых, существует три типа форм - FormControl, FormGroup и FormArray - все они наследуются от AbstractControl.

Когда вы используете Reactive Forms для проверки и включаете formGroupName, formControlName или formArrayName в шаблон компонента, вы фактически декларативно определяете карту между деревом управления формой и корневой FormGroup моделью.

Например, с учетом следующего шаблона:

<div [formGroup]="formGroup">
    <div formGroupName="personalInfo">
         First Name: <input type="text" formControlName="firstName"><br />
         Last Name: <input type="text" formControlName="lastName"><br />
    </div>
    <div formArrayName="cities">
        Top cities: <input *ngFor="let city of cities; index as i" type="text" [formControlName]="i">
    </div>
</div>

Вы декларативно настраиваете карту формы для сбора информации, которая в конечном итоге создаст объект JSON в определенном формате. Например, с учетом приведенной выше модели формы, formGroup.value вернет:

{
   "personalInfo": {
        "firstName: 'John',
        "lastName: 'Smith'
    },
    "cities": [
        "New York",
        "Winnipeg",
        "Toronto"
    ]
 }

После того, как вы объявили структуру вашей группы форм в шаблоне, вам необходимо обязательно создать соответствующие formGroup, formControl и formArray в вашем классе компонентов. При настройке каждой формы у вас есть возможность настроить дополнительные параметры:

  1. Initial Form Value
  2. Array of synchronous validators
  3. Array of asynchronous validators

Это относится к любому из абстрактных элементов управления.

Вот как будет выглядеть соответствующая модель formGroup с использованием приведенного выше шаблона:

export class AppComponent {
  firstName: string,
  lastName: string;
  cities: string[];
  @Input() formGroup: FormGroup;
  constructor(private fb: FormBuilder) {
    // setup initial values
    this.cities = ['New York', 'Winnipeg', 'Toronto'];
    this.firstName = 'John';
    this.lastName  = 'Smith';

    // create a formGroup that corresponds to the template
    this.formGroup = fb.group({
      firstName: [this.firstName, Validators.required],
      lastName: [this.lastName, Validators.required],
      cities: fb.array(this.cities.map(t=> fb.control(t, Validators.required)))
    })
  }
}

Для привязки к любому из флагов проверки формы вы можете использовать корень formGroup и строку пути (которая поддерживает точки), чтобы найти определенную группу, элемент управления или массив.

Например:

<div *ngIf="formGroup.get('firstName').errors.required">First Name is Required</div>

Надеюсь, это проясняет.

[Изменить]

Еще лучше, учитывая, что Reactive Forms - это декларативная настройка модели в шаблоне и обязательное сопоставление одной и той же модели в классе компонентов, вам следует рассмотреть возможность определения модели JSON и ее использования вместо этого.

Например, предположим, что у нас есть пользовательская модель MyModel, которая имеет свойство firstName, свойство lastName и свойство cities. Класс компонента будет выглядеть следующим образом:

 export class AppComponent {
  @Input() model: MyModel;
  @Output() modelChange: EventEmitter<MyModel>;

  @Input() formGroup: FormGroup;
  constructor(private fb: FormBuilder) {
    this.model = new EventEmitter<MyModel>();
    // create a formGroup that corresponds to the template
    this.formGroup = fb.group({
      firstName: [this.model.firstName, Validators.required],
      lastName: [this.model.lastName, Validators.required],
      cities: fb.array(this.model.cities.map(t=> fb.control(t, Validators.required)))
    });
  }

  onSubmit() {
     if (this.formGroup.valid) {
        this.model = this.formGroup.value;
        this.modelChange.next(this.model);
     }
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...