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

Почему мои ko вычисляемые наблюдаемые не обновляют связанные элементы пользовательского интерфейса при изменении его значения?

Я пытаюсь обернуть файл cookie в вычисленный наблюдаемый (который позже я перейду в protectedObservable), и у меня возникнут некоторые проблемы с вычисленным наблюдаемым. Я был убежден, что изменения в вычисленном наблюдаемом будут передаваться любым элементам пользовательского интерфейса, которые были привязаны к нему.

Я создал следующую скрипту

JavaScript

var viewModel = {};

// simulating a cookie store, this part isnt as important
var cookie = function () {  

    // simulating a value stored in cookies
    var privateZipcode = "12345";

    return {
        'write' : function (val) { privateZipcode = val; }, 
        'read': function () { return privateZipcode; }
    }
}();

viewModel.zipcode = ko.computed({
        read: function () {
            return cookie.read();
        },
        write: function (value) {
            cookie.write(value);
        },
        owner: viewModel
    });

ko.applyBindings(viewModel);?

HTML

zipcode:
<input type='text' data-bind="value: zipcode"> <br />

zipcode: 
<span data-bind="text: zipcode"></span>?

Я не использую наблюдаемый для хранения privateZipcode, так как это действительно будет в cookie. Я надеюсь, что ko.computed предоставит мне необходимые функции уведомлений и привязки, хотя большинство примеров которые я видел с помощью ko.computed, в конечном итоге используют a ko.observable под крышками.

Не должен ли акт записи значения для моего вычисленного наблюдаемого сигнала элементам пользовательского интерфейса, привязанным к его значению? Должны ли они просто не обновляться?

Обход

У меня есть простой способ, когда я просто использую ko.observable рядом с моим хранилищем файлов cookie, и использование этого приведет к появлению необходимых обновлений для моих элементов DOM, но это кажется совершенно ненужным, если только ko.computed не хватает сигналов/функциональность типа зависимостей, которая ko.observable имеет.

Моя обходная скрипта, вы заметите, что единственное, что меняется, это то, что я добавил seperateObservable, который не используется как хранилище, его единственный Цель состоит в том, чтобы сообщить пользовательскому интерфейсу, что базовые данные изменились.

// simulating a cookie store, this part isnt as important
var cookie = function () {  

    // simulating a value stored in cookies
    var privateZipcode = "12345";

    // extra observable that isnt really used as a store, just to trigger updates to the UI
    var seperateObservable = ko.observable(privateZipcode);

    return {
        'write' : function (val) { 
            privateZipcode = val; 
            seperateObservable(val);
        }, 
        'read': function () { 
            seperateObservable();
            return privateZipcode; 
        }
    }
}();

Это имеет смысл и работает так, как я ожидал бы, потому что viewModel.zipcode зависит от seperateObservable, и обновления, которые должны (и должны) сигнализировать об обновлении пользовательского интерфейса. Что я не понимаю,, почему не вызов функции write на моем ko.computed сигнализирует об обновлении пользовательского интерфейса, поскольку этот элемент привязан к этому ko.computed?

Я подозревал, что мне, возможно, придется что-то использовать в нокауте, чтобы вручную сообщить, что мой ko.computed был обновлен, и я в порядке с этим, это имеет смысл. Я просто не смог найти способ сделать это.

4b9b3361

Ответ 1

Вздох, я нашел кого-то с моя точно такая же проблема

Если dependObservables не уведомляет подписчиков о записи, почему они даже потрудились сделать это при чтении? Они добавляются в список наблюдаемых и подписались на них, но затем они никогда не запускаются при обновлениях. Итак, что точка подписания на них вообще?

Райан Нимейер отвечает:

Я думаю, что для вашего сценария, dependObservables может не быть правильный инструмент для работы. dependentObservables настроены для обнаружения зависимостей в функции чтения и переоценки/уведомления каждый раз, когда этих зависимостей. В зависимости от записи Функция записи - это просто место для перехвата записи и разрешения вы должны установить любые необходимые наблюдаемые данные, чтобы ваша функция чтения вернет правильное значение (запись, как правило, является обратной чтением в большинстве случаев, если вы не преобразуете значение).

В вашем случае я лично использовал бы наблюдаемый для представления а затем ручную подписку на наблюдаемую для обновления оригинальное значение (которое вы не можете контролировать).

Это будет выглядеть так: http://jsfiddle.net/rniemeyer/Nn5TH/

Итак, это выглядит как эта скрипка будет решением

var viewModel = {};

// simulating a cookie store, this part isnt as important
var cookie = function () {  

    // simulating a value stored in cookies
    var privateZipcode = "12345";

    return {
        'write' : function (val) { 
            console.log("updated cookie value with: " + val);
            privateZipcode = val; 
        }, 
        'read': function () { 
            return privateZipcode; 
        }
    }
}();

viewModel.zipcode = ko.observable(cookie.read());

// manually update the cookie when the observable changes
viewModel.zipcode.subscribe(function(newValue) {
   cookie.write(newValue);   
});

ko.applyBindings(viewModel);​

Это имеет смысл и его несколько проще в использовании. В целом я не уверен, насколько велика идея рассматривать cookie как наблюдаемую, поскольку сервер может редактировать ее в ajax-запросе и т.д.