17

我正在尝试将一个 cookie 包装在一个计算的 observable 中(我稍后会变成一个 protectedObservable)并且我在计算 observable 时遇到了一些问题。我认为对计算出的 observable 的更改将被广播到任何绑定到它的 UI 元素。

我创建了以下小提琴

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>?

我没有使用 observable 来存储privateZipcode,因为它实际上只是在 cookie 中。我希望ko.computed它将提供我需要的通知和绑定功能,尽管我看到的大多数示例最终ko.computed都使用了ko.observable底层。

将值写入我计算的 observable 的行为不应该向绑定到其值的 UI 元素发出信号吗?这些不应该更新吗?

解决方法

我有一个简单的解决方法,我只使用ko.observable我的 cookie 存储的旁边,使用它会触发对我的 DOM 元素的所需更新,但这似乎完全没有必要,除非ko.computed缺少具有的信号/依赖类型功能ko.observable

我的解决方法 fiddle,您会注意到唯一改变的是我添加了一个seperateObservable不用作存储的,它的唯一目的是向 UI 发出底层数据已更改的信号。

// 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和更新应该(并且确实)向 UI 发出更新信号。 我不明白的是,为什么write对我的函数的调用没有通知ko.computedUI 更新,因为该元素绑定到那个ko.computed

我怀疑我可能必须在淘汰赛中使用某些东西来手动表示我ko.computed的已更新,我对此很好,这是有道理的。我只是一直无法找到实现这一目标的方法。

4

2 回答 2

18

叹息,我找到了和我完全相同问题的人

如果dependentObservables 在写入时不通知订阅者,为什么他们甚至在读取时还要费心去做呢?它们被添加到 observables 列表并被订阅,但它们永远不会触发更新。那么订阅它们有什么意义呢?

瑞安尼迈耶回答:

我认为对于您的情况,dependentObservables 可能不是适合这项工作的工具。dependentObservables 设置为检测读取函数中的依赖关系,并在任何这些依赖关系发生变化时重新评估/通知。在可写的dependentObservable 中,write 函数实际上只是一个拦截写入并允许您设置任何必要的 observable 的地方,这样您的 read 函数将返回正确的值(在大多数情况下,write 通常是 read 的相反,除非您正在改变价值)。

对于您的情况,我个人会使用 observable 来表示该值,然后手动订阅该 observable 以更新原始值(您可能无法控制的值)。

就像: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 请求等中对其进行编辑。

于 2012-03-22T00:17:03.187 回答
0

尝试使您的内部私人邮政编码成为可观察的。见这里:http: //jsfiddle.net/KodeKreachor/fAGes/9/

于 2012-03-21T23:42:42.737 回答