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 computed observable never runs when I am changing the hashtable:
self.Querystring = ko.computed(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 computed 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.computed(function ()
{
var f = [];
$.each(self.MyHashKeys(), function (index, value)
{
f.push(encodeURIComponent(value) + '=' + encodeURIComponent(self.MyHash[value]));
});
return (f.length > 0) ? f.join("&") : "";
});