Я подозреваю, что это связано с тем, как вы обрабатываете обновления DOM. Ваш код только добавляет событие к последней кнопке. Это известная проблема с for/loop
с ). Использование forEach
вместо for / loop обычно исправляет это , но, по-видимому, не в этом случае. (Я ценю, что это немного волнообразно. У другого члена SO может быть более подробная техническая причина, почему это не работает в этом случае.)
Тем не менее, как вы обнаружили, вы гораздо лучше делать это поэтапно, но вы должны пойти еще на пару шагов. Это позволит избежать попадания в ситуацию, в которой вы сейчас находитесь, и будет более производительным.
В данный момент вы пытаетесь достичь всего за один цикл: создание html-задачи, добавление ее в DOM и добавление прослушивателя событий для новой кнопки. Что вам нужно сделать, это создать весь HTML, затем добавить , в DOM, затем взять все кнопки сразу, используя их класс, и добавить слушателей к ним.
const filteredTasks = [{ taskName: 'bob' },{ taskName: 'dave' }];
const tasks = document.querySelector('#tasks');
// Use `map` to create all the buttons
// I've used a data attribute here instead of an actual id
const html = filteredTasks.map(task => {
const buttonId = `${task.taskName.replace(/\s/g, '')}Button`;
return ``;
}).join('');
// Add that HTML to the DOM with one update
tasks.innerHTML = html;
// Grab all the taskButton buttons using their class,
// and add click listeners to them
const buttons = document.querySelectorAll('.taskButton');
[...buttons].forEach(button => button.addEventListener('click', performTask, false));
// `performTask` destructs the event target (clicked button)
// and logs the id
function performTask(e) {
const { dataset: { id } } = e.target;
console.log(id);
}
От MSDN:
[еще 116] информация о + бинарный оператор :В операциях конкатенации строк, компилятор C# рассматривает пустую строку то же как пустая строка, но это не преобразовывает значение исходной пустой строки.
двоичный файл + оператор выполняет конкатенацию строк, когда один или оба операнда имеют строку типа.
, Если операнд конкатенации строк является пустым, пустой строкой заменяют. Иначе любой неаргумент строки преобразовывается в свое строковое представление путем вызова виртуального метода ToString, наследованного от текстового объекта.
, Если пустой указатель возвратов ToString, пустой строкой заменяют.
Концептуально, строки обычно считаются значениями в противоположность ссылкам на объекты, которые имеют идентификационные данные. Одна из главных причин, что они не struct
с с семантикой значения, из-за издержек, которые идут с копированием на присвоении. Если бы строки были значения, то они не могли бы быть nullable и таким образом, null
просто рассматривается "+" оператор, как будто это была пустая строка (т.е. как будто default(string) == ""
так же, как default(int) == 0
).
Я предполагаю язык (или стандартная библиотека), разработчики решили, что это будет достаточно общим случаем, что они сделали бы программистам одолжение.
(Аккуратный! Я всегда просто предположил, что concating с пустым указателем будет посредством исключения!)
Причина это не выдает исключение нулевой ссылки, состоит в том, потому что Вы на самом деле не пытаетесь получить доступ к любым свойствам или методам на несуществующем объекте. Поскольку CMS заключает в кавычки, связывая строку, пустые указатели заменяются пустыми строками.
Я согласен, что концептуально строки - это просто значения. Однако рассмотрим следующий код:
int? i = null;
i += 1; // The result of this is that i == null
Если другие операторы типа значения использовали default () для преобразования строковых операторов в значение «», ваше объяснение имело бы смысл.
Проще всего сказать, что строковые операторы ярлык (особый случай) для удобства.