Как обновить значение FormArray переменной длины - PullRequest
1 голос
/ 16 октября 2019

Если я пытаюсь установить значение FormArray, когда FormArray пусто:

const array1 = new FormArray([]);
array1.setValue(['']);

Я получаю эту ошибку:

В этом массиве еще не зарегистрированы элементы управления формой,Если вы используете ngModel, вы можете проверить следующий тик

Если я добавлю 2, когда есть 1:

const array2 = new FormArray([new FormControl('')]);
array2.setValue(['', '']);

Я получаю следующую ошибку:

Не удается найти элемент управления формы по индексу 1

Если я пытаюсь установить 1 при наличии 2:

const array3 = new FormArray([new FormControl(''), new FormControl('')]);
array3.setValue(['']);

Я получаю следующую ошибку:

Необходимо указать значение для управления формой по индексу: 1.

Вопрос : Как написать функцию, которая может обновлять значение формыМассив со списком произвольной длины?

StackBlitz : https://stackblitz.com/edit/angular-wduzv9?file=src/app/app.component.ts

* edit Я понимаю, что могу использовать push(),at() и removeAt(0) методы. Я ищу функцию общего назначения. Он может использовать любые методы, которые вы хотите.

Ответы [ 3 ]

1 голос
/ 17 октября 2019

Упростите свои функции

getFormArray<T>(elements: T[]): FormArray {
    return new FormArray(
      elements.map((x: T) => {
        const obj = new FormGroup({});
        Object.keys(x).forEach(k => {
          obj.addControl(k, new FormControl(x[k]));
        });
        return obj;
      })
    );
  }

//the use, e.g.

this.formArray = this.getFormArray<any>([
  { id: 1, name: "Bob" },
  { id: 2, name: "Peter" }
]);

см. stackblitz

0 голосов
/ 16 октября 2019

Проблема в том, что добавить новые значения в новые ключи или индексы невозможно без знания типа AbstractControl, который вы хотите внутри FormArray в новом индексе.

Любое решение должно занятьучитывать, должен ли этот индекс быть FormControl, FormGroup или FormArray, следовательно, параметр toSubControl, который я предлагаю в моей функции setFormArrayValue. (Я также приведу несколько примеров значений для этого параметра.)

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

Вот решение, которое я придумала:

type ControlFactory<T> = (values: T) => AbstractControl;

export function setFormArrayValue<T>(
    array: FormArray,
    values: T[],
    toSubControl: ControlFactory<T> = toFormControl
) {
    while (array.length) {
        array.removeAt(0);
    }
    values
        .map(toSubControl)
        .forEach(function(control) {
            array.push(control);
        });
    return array;
}

Где следующие функции могут создать нового потомка AbstractControl s.

// When the child controls should be FormControl
function toFormControl<T>(value: T) {
    return new FormControl(value)
}

// When the child controls should be FormGroup
function toFormGroup<T>(item: T) {
    const fields = Object.entries(item).reduce(function(hash, [key, value]) {
        hash[key] = new FormControl(value);
        return hash;
    }, {});
    return new FormGroup(fields);
}

// When the child controls should be FormArray of FormControls
function toFormArray<T>(values: T) {
    const fields = values.map(value => new FormControl(value));
    return new FormGroup(fields);
}
0 голосов
/ 16 октября 2019

Вы можете инициализировать пустой formArray, а затем добавить элементы управления и затем установить значение,


const arr = new FormArray([]);

const a = new FormControl('a', []);
const b = new FormControl('b', []);
const c = new FormControl('c', []);

arr.push(a);
arr.push(b);
arr.push(c);

console.log(arr.value);   // ["a", "b", "c"] 
// arr.setValue([0]);

console.log(arr) 
arr.controls[0].setValue('xxx')

console.log(arr.value);   // "xxx", "b", "c"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...