Обработка и проверка группы флажков в Angular2
я не понимаю, как группы флажков должны обрабатываться в модели, управляемой формой в angular2.
модель имеет свойство languages
который я создаю вот так:
this.model = {
languages: []
};
используя FormBuilder
создать форму:
this.modelForm = this.formBuilder.group({
'languages': [model.languages, Validators.required],
});
и шаблона:
<div *ngFor="let language of translateService.get('languages') | async | key_value">
<input type="checkbox" name="languages[]" formControlName="languages" value="{{ language.key }}" id="language_{{ language.key }}">
<label attr.for="language_{{ language.key }}">{{ language.value }}</label>
</div>
на div
необходим для стилизации (пользовательский флажок),key_value
делает ключи и значения языка доступными в цикле, очевидно.
первый проблема связана с проверкой. Если один проверяет и снимает флажок (а другой флажок не установлен), вход по - прежнему действителен-как-то странно.
вторая проблема связана со значением, которое true
если два или более языков проверены и false
иначе.
тогда есть третья проблема с начальным значением languages
который является просто пустым массивом, но заставляет все флажки проверяться изначально (не происходит, если задано начальное значение к string
), хотя я не могу обнаружить любые checked
атрибут в DOM.
я работаю с последней ионной бета-версией (2.0.0-beta.10) который использует угловую/основную версию 2.0.0-rc.4 и угловой / формы версии 0.2.0.
Итак, есть ли руководство по работе с группами флажков? Какие-нибудь советы или идеи?
2 ответов
первая проблема связана с проверкой. Если один проверяет и снимает флажок (а другой флажок не установлен), вход по - прежнему действителен-как-то странно.
я заметил, что если значение languages
является пустым массивом, передает Validations.required
проверка.
вторая проблема связана со значением, которое равно true, если два или более языков проверены и false в противном случае.
тогда есть третья проблема с начальным значением языков, которое является просто пустым массивом, но заставляет все флажки проверяться изначально (не происходит, если начальное значение установлено в строку), хотя я не могу обнаружить какой-либо проверенный атрибут в DOM.
я думаю, что проблема заключается в том, как вы привязываете несколько элементов управления к одному FormControl
Я считаю FormArray
должен быть вовлечен, потенциально с другой FormControl
сохранение результата в массив чекбоксов.
Итак, есть ли руководство по работе с группами флажков? Какие-нибудь советы или идеи?
конечно, я сделал удар по его реализации, я сначала опубликую реализацию, а затем некоторые заметки. Вы можете просмотреть его в действии наhttps://plnkr.co/edit/hFU904?p=preview
@Component({
template: `
<template [ngIf]="loading">
Loading languages...
</template>
<template [ngIf]="!loading">
<form [formGroup]="modelForm">
<div [formArrayName]="'languages'" [class.invalid]="!modelForm.controls.selectedLanguages.valid">
<div *ngFor="let language of modelForm.controls.languages.controls; let i = index;" [formGroup]="language">
<input type="checkbox" formControlName="checked" id="language_{{ language.controls.key.value }}">
<label attr.for="language_{{ language.controls.key.value }}">{{ language.controls.value.value }}</label>
</div>
</div>
<hr>
<pre>{{modelForm.controls.selectedLanguages.value | json}}</pre>
</form>
</template>
`
})
export class AppComponent {
loading:boolean = true;
modelForm:FormGroup;
languages:LanguageKeyValues[];
constructor(public formBuilder:FormBuilder){
}
ngOnInit() {
this.translateService.get('languages').subscribe((languages:LanguageKeyValues[]) => {
let languagesControlArray = new FormArray(languages.map((l) => {
return new FormGroup({
key: new FormControl(l.key),
value: new FormControl(l.value),
checked: new FormControl(false),
});
}));
this.modelForm = new FormGroup({
languages: languagesControlArray,
selectedLanguages: new FormControl(this.mapLanguages(languagesControlArray.value), Validators.required)
});
languagesControlArray.valueChanges.subscribe((v) => {
this.modelForm.controls.selectedLanguages.setValue(this.mapLanguages(v));
});
this.loading = false;
});
}
mapLanguages(languages) {
let selectedLanguages = languages.filter((l) => l.checked).map((l) => l.key);
return selectedLanguages.length ? selectedLanguages : null;
}
}
главное отличие здесь в том, что я слил ваш model.languages
в своем modelForm
, а теперь повторяю на modelForm.languages
FormArray
в шаблоне.
modelForm.languages
стало modelForm.selectedLanguages
, и теперь является вычисленным значением на основе проверенных значений в modelForm.languages
. Если ничего не выбрано, modelForm.selectedLanguages
имеет значение null, чтобы не прошли проверку.
modelForm
не создается, пока не будут доступны языки, это в основном личные предпочтения, я уверен, что вы можете асинхронно прикрепить languages
и selectedLanguages
на modelForm
, но это упрощает вещи, чтобы построить его синхронно.
достал translateService.get('languages') | async
, я заметил, что некоторые странное поведение с этой функцией вызывается в шаблоне, и я предпочитаю разворачивать мои наблюдаемые в компоненте в любом случае, чтобы захватить состояния загрузки/ошибки.
это не так элегантно, как может быть некоторый собственный контроль формы массива флажков, но он чистый и очень гибкий. Проверьте в plunker и дайте мне знать если вы имеете любые вопросы!
Если вы установите флажок, а затем снимите его, FormControl все равно покажет его как действительный, даже если он не установлен. Может случиться так, что он принимает только истинные и ложные ценности.Вы можете попробовать этот образец кода, как он работал для меня -
mustBeChecked(control: FormControl): {[key: string]: string} {
if (!control.value) {
return {mustBeCheckedError: 'Must be checked'};
} else {
return null;
}
}
вы также можете обратиться к этой plunker
В настоящее время существует открытая проблема здесь, где триггеры события щелчка перед изменением значения. Обратитесь к ссылке GitHub здесь.Надеюсь, это может помочь вы.
существуют различные обходные пути для нескольких флажков, таких как использование
event.target.checked
вместо значения из модели.
вы можете использовать его как в этом примере -
<input type="checkbox"
(change)="expression && expression.Option1=$event.target.checked ? true : undefiend"
[ngModel]="expression?.Option1">
<input type="checkbox"
(change)="expression && expression.Option2=$event.target.checked ? true : undefiend"
[ngModel]="expression?.Option2">