最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

knockout.js - How do you observe JavaScript hashtables in Knockout? - Stack Overflow

programmeradmin6浏览0评论

In my Knockout viewmodel, I've got some properties where I'm trying to make a hash observable. So instead of my pre-Knockout code of

self.MyHash = {};

I am now using:

self.MyHash = ko.observable({});

In other parts of my code, I am manipulating the hash with statements like these:

// add an entry
self.MyHash()["test"] = "My Value";

// remove an entry
delete self.MyHash()["test"];

The code works, in that the entries are added and removed properly. However, the changes to the hashtable don't seem to be detected by areas of the code that are observing it. For example, this puted observable never runs when I am changing the hashtable:

self.Querystring = koputed(function ()
{
    var f = [];
    $.each(self.MyHash(), function (k, v)
    {
        f.push(encodeURIComponent(k) + '=' + encodeURIComponent(v));
    });

    return (f.length > 0) ? f.join("&") : "";
});

I am going to guess that this is because Knockout observables are required to be simple variables (or observableArrays), and that it's not detecting the underlying changes to my hashtable.

If so, are there other options? Why isn't there an observableHash type in Knockout?

For what it's worth, my workaround is to have an observableArray of keys, and a regular JavaScript hashtable to lookup the values. Then I changed my puted method to observe the array of keys rather than the other hashtable variable I had before. I just want to make sure I'm not missing "The Right Way" to do it in Knockout.

self.MyHashKeys = ko.observableArray();
self.MyHash = {};

self.Querystring = koputed(function ()
{
    var f = [];
    $.each(self.MyHashKeys(), function (index, value)
    {
        f.push(encodeURIComponent(value) + '=' + encodeURIComponent(self.MyHash[value]));
    });

    return (f.length > 0) ? f.join("&") : "";
});

In my Knockout viewmodel, I've got some properties where I'm trying to make a hash observable. So instead of my pre-Knockout code of

self.MyHash = {};

I am now using:

self.MyHash = ko.observable({});

In other parts of my code, I am manipulating the hash with statements like these:

// add an entry
self.MyHash()["test"] = "My Value";

// remove an entry
delete self.MyHash()["test"];

The code works, in that the entries are added and removed properly. However, the changes to the hashtable don't seem to be detected by areas of the code that are observing it. For example, this puted observable never runs when I am changing the hashtable:

self.Querystring = ko.puted(function ()
{
    var f = [];
    $.each(self.MyHash(), function (k, v)
    {
        f.push(encodeURIComponent(k) + '=' + encodeURIComponent(v));
    });

    return (f.length > 0) ? f.join("&") : "";
});

I am going to guess that this is because Knockout observables are required to be simple variables (or observableArrays), and that it's not detecting the underlying changes to my hashtable.

If so, are there other options? Why isn't there an observableHash type in Knockout?

For what it's worth, my workaround is to have an observableArray of keys, and a regular JavaScript hashtable to lookup the values. Then I changed my puted method to observe the array of keys rather than the other hashtable variable I had before. I just want to make sure I'm not missing "The Right Way" to do it in Knockout.

self.MyHashKeys = ko.observableArray();
self.MyHash = {};

self.Querystring = ko.puted(function ()
{
    var f = [];
    $.each(self.MyHashKeys(), function (index, value)
    {
        f.push(encodeURIComponent(value) + '=' + encodeURIComponent(self.MyHash[value]));
    });

    return (f.length > 0) ? f.join("&") : "";
});
Share Improve this question edited Apr 10, 2012 at 12:58 Paul Tyng 7,5841 gold badge35 silver badges57 bronze badges asked Apr 10, 2012 at 0:44 Mason G. ZhwitiMason G. Zhwiti 6,54012 gold badges64 silver badges99 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 7

See the second example on the observable array page. Just make an array of key/value pairs:

// This observable array initially contains three objects
var anotherObservableArray = ko.observableArray([
    { name: "Bungle", type: "Bear" },
    { name: "George", type: "Hippo" },
    { name: "Zippy", type: "Unknown" }
]);

In your examples you are only iterating (except for deletion), so there is no real need to use an actual dictionary. It would be easy enough to just search for the key. I think the use of map is kind of a premature optimization to some extent. Its also not entirely in line with the ability of query strings to support the same key multiple times.

Edit: if you want to observe the key or value changing in this example, you would also have to make those properties observable:

var anotherObservableArray = ko.observableArray([
    { name: ko.observable("Bungle"), type: ko.observable("Bear") }
]);
发布评论

评论列表(0)

  1. 暂无评论