Почему моя вычисляемая Ко наблюдаемая не обновляет связанные элементы пользовательского интерфейса при изменении его значения? - PullRequest
17 голосов
/ 22 марта 2012

Я пытаюсь обернуть 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, заканчиваются использованием ko.observable под крышками.

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

Обход

У меня есть простой обходной путь, когда я просто использую ko.observable рядом с моим хранилищем печенья и использую его, чтобы вызвать необходимые обновления для моих элементов 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 обновлен, и я в порядке с этим, в этом есть смысл. Я просто не смог найти способ сделать это.

Ответы [ 2 ]

18 голосов
/ 22 марта 2012

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

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

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

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

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

Это было бы как: 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-запросе и т. Д.

0 голосов
/ 22 марта 2012

Попробуйте сделать свой внутренний частный почтовый индекс видимым. Смотрите здесь: http://jsfiddle.net/KodeKreachor/fAGes/9/

...