Материал-checkboxes.component Angular FormControl имеет выбранные значения, но this.controlValue является пустым массивом

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

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

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

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

И вот результаты представленных значений (как и ожидалось):

Для сравнения представлен тот же элемент управления (material-checkboxes.component.ts), но построенный с использованием внешнего источника данных для подачи в titleMap и также имеющий значения по умолчанию.

И вот результат после отправки формы выше:

Итак, как показывают снимки экрана, созданный вручную файл работает должным образом и отправляет форму, содержащую значения по умолчанию. Однако компонент с динамически генерируемыми значениями, даже если в представлении показано, что для него выбраны параметры по умолчанию, отправляется как ПУСТОЙ.

Ожидается: this.controlValue = ['12', 'd4']

Действительный:

onInit> this.controlValue = ['12', 'd4']

После метода updateValue> this.controlValue = undefined // Но вид не изменился с момента инициализации

Однако я могу заставить его отправлять данные, как ожидалось, если я вручную изменю любое из значений, даже если я установлю их точно так, как они были заданы по умолчанию. Это как если бы данные формы не устанавливались, пока вручную не щелкнули параметры.

Вот фрагмент из шаблона, который содержит компонент:

      <mat-checkbox
    type="checkbox"
    [class.mat-checkboxes-invalid]="showError && touched"
    [class.mat-checkbox-readonly]="options?.readonly"
    [checked]="allChecked"
    [disabled]="(controlDisabled$ | async) || options?.readonly"
    [color]="options?.color || 'primary'"
    [indeterminate]="someChecked"
    [name]="options?.name"
    (focusout)="onFocusOut()"
    (change)="updateAllValues($event)"
    [required]="required"
    [value]="controlValue">

1 ответ

Обновление: я обнаружил, что проблема заключалась в том, что значение элемента управления формы не обновлялось до выхода из прослушивателя хоста setTitleMap. Добавление вызова к this.updateValue() разрешает его, и модель и представление снова синхронизируются. Однако есть проблема, но сначала вот код, который решает проблему, когда в данных this.options задано значение по умолчанию:

      @HostListener('document:setTitleMap', ['$event'])
  setTitleMap(event: CustomEvent) {
    if (event.detail.eventName === this.options.wruxDynamicHook && isRequester(this.componentId, event.detail.params)) {
      this.checkboxList = buildTitleMap(event.detail.titleMap, this.options.enum, true, true, this.options.allowUnselect || false);
      // Data coming in after ngInit. So if this is the first time the list is provided, then use the defaultValues from the options.
      const value = this.setDefaultValueComplete ?
        this.jsf.getFormControl(this)?.value || [] :
        [].concat(this.options?.defaultValue || []);
      this.syncCurrentValues(value);
      this.updateValue(); // Fixed it. Otherwise, the checked items in titlemap never get synced to the model
      // Set flag to true so we ignore future calls and not overwrite potential user edits
      this.setDefaultValueComplete = true;
    }
  }

updateValue(event: any = {}) {
  this.options.showErrors = true;
  // this.jsf.updateArrayCheckboxList(this, this.options.readonly ? this.checkboxListInitValues : this.checkboxList);
  this.jsf.updateArrayCheckboxList(this, this.checkboxList);
  this.onCustomAction(this.checkboxList);
  this.onCustomEvent(this.checkboxList);
  this.jsf.forceUpdates();
  if (this.jsf.mode === 'builder-properties') {
    this.jsf.elementBlurred();
  }
}

syncCurrentValues(newValues: Array<any>): void {
  for (const checkboxItem of this.checkboxList) {
    checkboxItem.checked = newValues.includes(checkboxItem.value);
  }
}

Вызов updateData() выше устраняет проблему в этом случае. Однако, когда в данных опций нет значений по умолчанию и данные флажка загружаются извне из вызова API, который выполняется после запуска ngOnInit, у меня возникает та же проблема. this.controlValue пуст после ngOnInit, несмотря на то, что представление обновилось, чтобы отображать отмеченные флажки. Модель сделала это с помощью метода setTitleMap(), но controlValue по-прежнему регистрируется как пустой массив.

Другие вопросы по тегам