2016-10-27 7 views
1

У меня есть массив строк, связанных с входными элементами:Aurelia: Удаление элементов массива при изменении на пустое значение

<div repeat.for="i of messages.length"> 
    <input type="text" value.bind="$parent.messages[i]"> 
</div> 

Мне нужно удалить элемент, когда содержание ввода удаляются, без использования грязной проверки.

Это звучит просто: просто удалите элемент, который имеет пустое значение из обработчика input.delegate, к сожалению, это не работает из-за Aurelia bug #527. Вот суть, которая пробует этот подход: https://gist.run/?id=e49828b236d979450ce54f0006d0fa0a

Я попытался обойти ошибку, используя queueTask, чтобы отложить удаление элемента массива, но безрезультатно. И так как разработчики закрыли ошибку, потому что, по их словам, это дубликат совершенно не связанной проблемы, я думаю, что она не будет исправлена ​​в ближайшее время.

У меня нет идей, как реализовать это, поэтому любые предложения приветствуются.

+0

Что вы подразумеваете под «без использования грязной проверки»? как вы уверены, что здесь грязная проверка? это работает на данный момент, и вы просто хотите оптимизировать свой код, или он вообще не работает? –

+0

Я попытался сделать это без грязной проверки (см. Связанный смысл), и он не работает из-за ошибки Aurelia. Грязная проверка будет искать массив каждые 100 мс и удалять любые пустые элементы, это сработает, но я хочу этого избежать. –

+0

см. [Это сообщение в блоге] (http://ilikekillnerds.com/2015/10/observing-objects-and-arrays-in-aurelia/), или [этот пост stackoverflow] (http://stackoverflow.com/a/32019971/547020). –

ответ

1

Абсолютно никакой необходимости в каких-либо грязных проверках здесь! :)

Вот рабочий пример для сценария: https://gist.run/?id=20d92afa1dd360614147fd381931cb17

  • $ родитель больше не нужен. Это было связано с версиями до версии 1.0 Aurelia.
  • Если вы используете переменную вместо индексов массива, вы можете использовать двустороннюю привязку данных, предоставляемую вводом.
<template> 
    <div repeat.for="msg of messages"> 
    <input type="text" value.bind="msg" input.delegate="onMessageChanged(msg, $index)"> 
    </div> 
</template> 

Итак, ваше событие OnChange можно упростить следующим образом:

  • msg имеет фактическое значение текущего входного сигнала.
  • i указатель будет использован для удаления.
export class App { 
    messages = ['Alpha','Bravo','Charlie','Delta','Echo']; 

    onMessageChanged(msg, i){ 
    if (!msg || msg.length === 0) { 
     this.messages.splice(i, 1); 
    } 
    } 
} 

Был связанный с этим вопрос о подобной проблеме. This answer может дать вам более подробную информацию об основной идее.

+0

отлично звучит (и работает тоже!). как вы можете быть уверены, что грязная проверка продолжается? –

+0

Aurelia использует методы наблюдения, чтобы избежать обычной проверки грязных поверхностей. Есть некоторые случаи, когда он возвращается к грязной проверке, но это не относится к вашему делу (простая двусторонняя привязка данных). Большую часть времени вы можете полагаться на встроенных наблюдателей Aurelia, не выполняя специальные грязные проверки. Дополнительная информация: [Документы] (http://aurelia.io/hub.html#/doc/article/aurelia/binding/latest/binding-how-it-works/1), [блог Джереми Даньюва (возможно, устаревшее, но полезное чтение)] (https://www.danyow.net/aurelia-property-observation/) –

+0

thanx, я знаю об этом, просто спрашивая практически - может ли он быть протестирован в браузере? например если я создаю getter * без * декодирования 'computedFrom' и помещаю в консольный журнал внутри, я могу видеть вызовы механизма грязной проверки. есть ли другой способ сказать (доказать), если грязная проверка включена для определенного свойства? –

-2

Итак, решение это не использовать багги (в данном случае) AURELIA 2-связывания, но использовать 1-способ связывания и установить значение от input.delegate обработчика:

https://gist.run/?id=2323c09ec9da989eed21534f177bf5a8

Ответ на @marton кажется с первого взгляда, но фактически отключает двухстороннюю привязку, поэтому любые изменения в входах не копируются в массив. Но это дало мне важный намек на то, как решить проблему. эквивалент этого HTML-код:

<div repeat.for="msg of messages"> 
    <input type="text" value.bind="msg"> 
</div> 

это:

for (let msg of messages) { 
    msg = 'something else'; // note: this does not change the contents of the array 
} 

См issue #444 для более подробной информации

Таким образом, это вынуждает одну сторону переплета. Чтобы исправить это в решении @marton, нам нужно только изменить значение из ввода.делегат-обработчик:

onMessageChanged(msg, i){ 
    if (!msg || msg.length === 0) { 
    this.messages.splice(i, 1);//delete the element 
    } 
    else { 
    this.messages[i] = msg;//change the value 
    } 
} 
+1

почему вы считаете, что привязка aurelia-2-way является ошибкой, если она делает то, что ожидается? –

+0

Это ошибка в случае, описанном в этом вопросе. Кажется, что одно изменение входного значения применяется к модели представления дважды - до и после вызова обработчика input.delegate. Это проблема, когда обработчик удаляет элемент из массива. Поскольку массив изменился - во второй раз Aurelia перезаписывает несвязанный элемент. См. Этот пример для простого примера: https://gist.run/?id=f3e7002bf3b60472313b8f9c5963c7c4 Это объясняется в связи с ошибкой, связанной с этим вопросом. –

+1

@AngelPopov: Я показал вам обход для обработки удаления, я думаю, что это был объем вышеупомянутого вопроса. :) Хотя, я предположил, что вы хотели бы сделать больше, поэтому я указал вам на другой ответ. С одной стороны, вы теряете преимущество неявных обновлений массива, используя ссылку msg. Но, с другой стороны, Aurelia предоставляет вам достаточную контекстуальную информацию (например, $ index), чтобы обеспечить легкий способ обновления «сообщений» вручную при изменении входного значения. –