Я «утешаю» весь код... но не могу найти никаких проблем, только странное поведение.
Позволь мне объяснить: У меня есть угловой компонент (назовем его родительским), который отправляет некоторые теги своему ребенку через массив inputTags. Затем мне нужно установить другой список со ВСЕМИ тегами пользователя, который называется allTags.
Массив (как inputTags, так и allTags) отформатирован следующим образом: {идентификатор: 'tagId', имя: 'tagName'}
Мне нужно сделать единый массив из этих двух. Ожидаемый результат должен содержать массив элементов, отформатированных следующим образом: { id: 'tagId', name: 'tagName', selected: boolean }
Для этого я сопоставляю массив allTags следующим образом:
Предположим, что:
inputTags = [
{ id: 'work', name: 'Work' },
{ id: 'motivation', name: 'Motivation' }
];
allTags = [
{ id: 'network', name: 'Network' },
{ id: 'work', name: 'Work' },
{ id: 'smart', name: 'Smart' },
{ id: 'motivation', name: 'Motivation' }
];
Теперь... все теги фактически извлекаются с сервера, поэтому мой код выглядит примерно так:
this.tagsService.getAll().subscribe(tags => {
this.allTags = tags.map(tag => {
let select = false;
this.inputTags.forEach(inputTag => { select = (inputTag.id === tag.id) })
return {
id: tag.id,
name: tag.name,
selected: select,
};
});
})
Это для меня кажется вполне стандартным, но на самом деле НЕТ, потому что вместо получения:
allTags = [
{ id: 'network', name: 'Network', selected: false },
{ id: 'work', name: 'Work', selected: true }, // is selected
{ id: 'smart', name: 'Smart', selected: false },
{ id: 'motivation', name: 'Motivation', selected: true } // is selected
];
Я получаю это:
allTags = [
{ id: 'network', name: 'Network', selected: false },
{ id: 'work', name: 'Work', selected: false }, // is NOT selected
{ id: 'smart', name: 'Smart', selected: false },
{ id: 'motivation', name: 'Motivation', selected: true } // is selected
];
В основном проблема в том, что он выбирает только один тег, а не несколько тегов.
Метод карты массива JavaScript ()
*) создает новый массив с результатами вызова функции для каждого элемента массива и вызывает предоставленную функцию один раз для каждого элемента в массиве по порядку.
Примечание: map()
Метод не выполняет функцию для элементов массива без значений и не изменяет исходный массив.
Попробуйте следующее:
this.allTags = allTags.map(tag => ({
id: tag.id,
name: tag.name,
selected: inputTags.some(i => i.id === tag.id),
}))
Это работает спасибо! Было бы лучше использовать ответ Амаду Бей, используя «some ()», или ваш?
Комбинация того и другого, с использованием some()
, но без возврата, как у меня :)
Вы можете попробовать некоторые:
this.allTags = tags.map(tag => {
return {
id: tag.id,
name: tag.name,
selected: this.inputTags.some(inputTag => inputTag.id === tag.id)
};
});
Это работает спасибо! Было бы лучше использовать ответ Санти Барбата, используя «find ()» и тернарный оператор, или ваш?
@PietroLungarini оба верны, но этот короче
.forEach()
неправильно. Вы получите результат сравнения «id» только для последнего элемента в списке, потому чтоselect
безусловно обновляется каждый раз.