Материал-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 по-прежнему регистрируется как пустой массив.