Angular- запретить выбор одинаковых параметров из раскрывающегося списка.
Я сделал материальный диалог с раскрывающимся списком и текстовым полем. Это код:
export class ModalAllComponent implements OnInit {
dialogData: DialogDataModel;
languages: any[];
rows: any[];
item!:any[];
constructor(
public dialogRef:MatDialogRef<ModalAllComponent>,
@Inject(MAT_DIALOG_DATA) public data: DialogDataModel) {
this.dialogData = data;
this.rows = this.dialogData.localisedEntities.filter(lang => lang.value,)
this.languages = this.dialogData.localisedEntities.map(item => ({ code: item.code, title: item.title, canEdit: item.canEdit }))
}
ngOnInit(): void {
}
addNewLanguage() {
this.rows.push({
code: '',
title: '',
value: '',
canEdit: true
});
}
onChangeValue(ev: any){
this.rows = this.rows.map(row => {
if (row.code == ev.value) {
const lang = this.languages.find(lang => lang.code == ev.value);
row.title =lang.title;
}
return row;
})
this.languages = this.languages.map(lang => {
if (lang.code == ev.value) {
lang.canEdit = false;
}
return lang;
});
console.log(this.languages)
this.isDisabled()
}
isDisabled(){
return this.rows.filter((item) => item.value == '' || item.code == '')
.length > 0
? true
: false;
}
Здесь, если я нажму
addNewLanguage()
и добавьте новую строку, параметры заблокируются. Вот так,но если я ударил
submit()
а затем попробуйте добавить новую строку, это происходит. Как запретить пользователям выбирать один и тот же параметр даже после его однократной отправки.
3 ответа
При выборе получите выбранный элемент внутри функции и отфильтруйте массив языков.
Перед тем как погрузиться в ...
Поскольку, как вы сказали, это большой проект, мне кажется, что его сложно диагностировать, но я укажу на то, что, по моему мнению, может быть виновником, основываясь на вещах, которые я видел раньше, и обновлю этот ответ. если появятся более подробные сведения / контекст.
А пока проверьте это: https://stackoverflow.com/help/minimal-reproducible-example.
Послушайте, я знаю, это все очевидные вещи, я не хочу оскорблять, но мы, программисты, часто забываем об этом, когда сосредоточиваемся на проблеме, и напоминание часто бывает полезным. Суть в том, что минимальный воспроизводимый пример - это много миль для помощи отвечающим и задающему вопрос, в свою очередь. Мы глубоко признательны за любой прогресс, которого вы можете добиться в этом направлении!
Что может происходить
Кажется, что эта проблема лучше подходит для реактивных форм, чем для форм на основе шаблонов, но вы можете использовать шаблоны форм. Вам нужна некоторая логика в сеттере, который привязан к вашей двусторонней привязке. Вот где вам нужно обновить
canEdit
положение дел.
Также я с подозрением отношусь к вашей подписке. В зависимости от того, что
dialogRef.afterClosed()
возвратов (с точки зрения количества выбросов, их источника и т. д.), у вас может возникнуть проблема с подпиской. Подписка не умирает вместе с компонентом. И даже если это не вызовет логической ошибки, это приведет к раздутию вашей памяти и замедлению работы вашего приложения.
И в целом, я бы рекомендовал найти способ не подписываться явно, а посмотреть, можете ли вы вместо этого использовать канал и просто отправлять любые изменения через
subject
что ты
.next
в конкретном месте вашего кода прослушивания событий (т.е.
ngModel
связанного сеттера). Другое преимущество заключается в том, что
async
pipe обрабатывает подписку за вас, но также откажется от подписки, когда компонент умирает.
Я вернусь, чтобы обновить, если это не решит вашу проблему и если вы сможете предоставить больше контекста. Извините, сейчас это просто догадки. Было бы полезно больше контекста!
Вместо жесткого кодирования
item.code == 'en'
, так что всякий раз, когда он видит
en
это повернет флаг
false
:
localiseFoodName() {
const dialogData = < DialogDataModel > {
localisedEntities: this.foodModel.localisedName.map((item: any) => {
if (item.code == 'en') {
item.canEdit = false;
} else {
item.canEdit = true;
}
return item;
}),
};
Я только что проверил, является ли значение элемента null(пустым) с этим
item.value != null
:
localiseFoodName() {
const dialogData = < DialogDataModel > {
localisedEntities: this.foodModel.localisedName.map((item: any) => {
if (item.value != null) {
item.canEdit = false;
} else {
item.canEdit = true;
}
return item;
}),
};
console.log(dialogData);
let dialogRef = this.dialog.open(ModalAllComponent, {
width: '26.5rem',
data: dialogData
});
dialogRef.afterClosed().subscribe(res => {
if (res && res.data) {
console.log(res.data)
this.foodModel.localisedName.map((item:any)=>{
this.temp = res.data.find((element:any)=> element.code === item.code);
if(this.temp){
item.value = this.temp.value
}
})
}
})
}