Доступ к ссылке FormArray в ng-шаблоне - PullRequest
1 голос
/ 24 июня 2019

У меня есть компонент, который отображает некоторые поля формы в зависимости от данного объекта.Обычно компонент вызывается в цикле родительским компонентом, который каждый раз дает новый объект, затем дочерний компонент отображает нужный элемент в зависимости от типа.

ВотПример StackBlitz

Но иногда элемент может быть повторяемым , повторяемым элементом (в случае FormArray).У меня есть следующий код:



  
    index: {{ index }}
{{question.label}} {{question.placeholder}} {{opt.value}}
{{question.label}} требуется
</ ng-template>
val {{questionArray.value |json}}
</ ng-container>

на данный момент я проверяю повторяемость элемента только на inputs .

Так что для одного элемента это работает хорошо, ноон не может получить ссылку на необязательную директиву: [attr.formArrayName]="!!question.iterable ? question.key : null"

Если попытаться сделать следующее (поместить ввод непосредственно в ng-container, без вызова ng-template:

  <div *ngIf="question.iterable; else formTmpl">
    val {{questionArray.value | json}}
    <div *ngFor="let field of questionArray.controls; let i=index; last as isLast">
      <input [class]="isValid ? config.validClass : config.invalidClass"
             [formControlName]="i"
             [placeholder]="question.placeholder"
             [id]="question.key"
             [type]="question['type']">
      <button *ngIf="question.iterable && isLast"
              type="button"
              (click)="addItem(question)">+</button>
    </div>
  </div>

поле ввода хорошо видно, и значение формы хорошо привязано к нему.

Что странно, что formControlName каждого поля внутри ng-template имеет свое значение, хорошо связывающееся с формой.

Ошибка, которую я получил при инициализации формы:

ERROR Error: Cannot find control with unspecified name attribute
    at _throwError (vendor.js:74769)
    at setUpControl (vendor.js:74593)
    at FormGroupDirective.addControl (vendor.js:78338)
    at FormControlName._setUpControl (vendor.js:78989)
    at FormControlName.ngOnChanges (vendor.js:78912)
    at checkAndUpdateDirectiveInline (vendor.js:59547)
    at checkAndUpdateNodeInline (vendor.js:70213)
    at checkAndUpdateNode (vendor.js:70152)
    at debugCheckAndUpdateNode (vendor.js:71174)
    at debugCheckDirectivesFn (vendor.js:71117)

Затем, если я добавлю новый элемент в formArray, новый элемент появится, но не будети это новое сообщение об ошибке показывает:

ERROR Error: Cannot find control with name: '1'
    at _throwError (vendor.js:74769)
    at setUpControl (vendor.js:74593)
    at FormGroupDirective.addControl (vendor.js:78338)
    at FormControlName._setUpControl (vendor.js:78989)
    at FormControlName.ngOnChanges (vendor.js:78912)
    at checkAndUpdateDirectiveInline (vendor.js:59547)
    at checkAndUpdateNodeInline (vendor.js:70213)
    at checkAndUpdateNode (vendor.js:70152)
    at debugCheckAndUpdateNode (vendor.js:71174)
    at debugCheckDirectivesFn (vendor.js:71117)

Итак, как я могу создать поле с учетом свойства formArrayName?

Как видно ниже, атрибут присутствует в разметке(но я думал, что это было ng-reflect-name нормально), но это все равно не работает:

enter image description here

В качестве заключительного примера, вот скриншот формы (обратите внимание на индексы над каждым повторяемым входом):

enter image description here

Вот пример StackBlitz

1 Ответ

2 голосов
/ 25 июня 2019

я думаю [attr.formArrayName]="!!question.iterable ? question.key : null" привязка не работает, потому что она выполняется как привязка атрибута вместо привязки ввода

однако, когда мы конвертируем его в привязку ввода, в вашем случае возникают новые ошибки для вопросов, не относящихся к FormArray.

так что использование старой доброй директивы formControl вместо formControlName решает проблему.

[formControl]="form.get(question.iterable ? [question.key, index] : question.key)"

также при таком подходе вам больше не требуется [attr.formArrayName]="!!question.iterable ? question.key : null" привязка

вот рабочая демоверсия

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...