Обновить наблюдаемый массив, когда предметы не являются наблюдаемыми
В основном у меня есть наблюдаемый массив, и значения для каждого элемента не являются наблюдаемыми. Это означает, что когда я изменяю значение элемента, пользовательский интерфейс внутри цикла foreach наблюдаемого массива не обновляется соответствующим образом.
Это означает массовое изменение, если мне нужно установить их на наблюдаемые, так же как я могу обновить интерфейс UI или наблюдаемый массив foreach вручную?
Ответы
Ответ 1
Да, вы можете вызвать функцию valueHasMutated
для вашего массива:
yourArray.valueHasMutated();
EDIT:
Если сначала не помогло, вы можете сделать "грязное" обновление:
self.refresh = function(){
var data = self.array().slice(0);
self.array([]);
self.array(data);
};
Здесь работает скрипка: http://jsfiddle.net/vyshniakov/FuEy6/2/
Ответ 2
Когда у вас есть наблюдаемый массив с не наблюдаемыми элементами, и некоторые свойства одного из элементов в массиве меняются, если вы хотите обновить только этот элемент, вы можете использовать indexOf
и splice
, например:
var changedIdx = obsArray.indexOf(changedItem);
obsArray.splice(changedIdx , 1); // removes the item from the array
obsArray.splice(changedIdx , 0, changedItem); // adds it back
Что это значит, ищет элемент в массиве, удаляя его и вставляя обратно. Когда он вставлен обратно, элемент снова связан с новыми значениями.
Если вам нравится это решение, вы можете расширить функциональность всех наблюдаемых массивов ko, например:
ko.observableArray.fn.refresh = function (item) {
var index = this['indexOf'](item);
if (index >= 0) {
this.splice(index, 1);
this.splice(index, 0, item);
}
}
Затем, когда вы меняете элемент массива, вам просто нужно сделать этот вызов:
obsArray.refresh(changedItem);
Если у вас много элементов в вашем массиве, вы получите улучшенную производительность в отношении обновления dirty
Артема Вышнякова, который обновляет привязки для всех элементов в массиве, а не только для измененного.
Примечание: valueHasMutated
, appart из недокументированного (и для внутреннего использования, я полагаю), проверяет, изменился ли сам массив, а не если не наблюдаемые элементы в массиве изменились, т работы. То есть он обнаруживает, только если вы добавили элементы в массив, удалили элементы из массива, изменили элементы массива с новыми, разными элементами или изменили порядок элементов. Но он не проверяет, изменились ли сами элементы
Ответ 3
Я закончил использовать грязный подход сверху, но сделал так, чтобы все мои наблюдаемые массивы имели эту функциональность.
ko.observableArray.fn.refresh = function () {
var data = this().slice(0);
this([]);
this(data);
};
ЗначениеHasMutated не работает для меня. Его вид хромого, весь список должен быть обновлен. Или в моем случае найдите способ расширения плагина отображения ko, чтобы заполнить наблюдаемые массивы наблюдаемыми объектами.
Ответ 4
Я нашел простое решение, заменив весь объект в массиве.
В этом примере параметр ix - это индекс, oLine - это обновленный объект, а oVM.objProps.lines содержит массив. Решение работало как чемпион.
/* This contortion causes the computed function to fire because
* we have replaced the entire line object.
*/
function forceRefresh(ix,oLine) {
var oVM = pme.getVM();
oLine = JSON.parse(JSON.stringify(oLine));
oVM.oObjProp.lines[ix] = oLine;
}