Подтвердить что ты не робот

Обновить наблюдаемый массив, когда предметы не являются наблюдаемыми

В основном у меня есть наблюдаемый массив, и значения для каждого элемента не являются наблюдаемыми. Это означает, что когда я изменяю значение элемента, пользовательский интерфейс внутри цикла foreach наблюдаемого массива не обновляется соответствующим образом.

Это означает массовое изменение, если мне нужно установить их на наблюдаемые, так же как я могу обновить интерфейс UI или наблюдаемый массив foreach вручную?

4b9b3361

Ответ 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;
}