问题
I'm following this post:
http://www.knockmeout.net/2012/05/using-ko-native-pubsub.html
to allow one of my vms to communicate with the other. One of my viewModels has an array that I need to expose to another viewModel. If this array is not an observable, the method from the above post works just fine.
If the array is an observable array, publishedSelectedFolders is never populated. I'm trying to figure out why; hopefully it's something silly I'm doing.
Here's my jsFiddle:
http://jsfiddle.net/PTSkR/40/
If you uncomment the line in the vm, it works as expected (publishedSelectedFolders is populated as checks are ticked). Why is this happening?
Code:
/*
* Pub/Sub (decouples VMs but lets them access each others' data)
*/
var postbox = new ko.subscribable();
ko.subscribable.fn.publishOn = function (topic) {
this.subscribe(function (newValue) {
postbox.notifySubscribers(newValue, topic);
});
return this; //support chaining
};
ko.subscribable.fn.subscribeTo = function (topic) {
postbox.subscribe(this, null, topic);
return this; //support chaining
};
/* Selection code */
this.publishedSelectedFolders = ko.observableArray().subscribeTo("SELECTED_FOLDERS");
var vm = {
folders: ko.observableArray([{
"folderId": "1"
}, {
"folderId": "2"
}]),
// folders: [{"folderId": "1"}, {"folderId": "2"}, {"folderId": "3"}],
selectedFolderIds: ko.observableArray(),
};
vm.folderIndex = {};
ko.utils.arrayForEach(vm.folders, function (folder) {
vm.folderIndex[folder.folderId] = folder;
});
/* monitors selections and publishes to the shell */
this.selectedFolders = ko.computed(function () {
return ko.utils.arrayMap(vm.selectedFolderIds(), function (id) {
return vm.folderIndex[id];
});
}).publishOn("SELECTED_FOLDERS");
ko.applyBindings(vm);
回答1:
The ko.utils.array...
helpers do not unwrap observables automatically (see source on github). So you need to pass them the already unwrapped arrays and not the observableArray
directly.
So the error is in your arrayForEach
call, where the correct usage is:
ko.utils.arrayForEach(viewModel.documents(), function(doc) {
viewModel.documentIndex[doc.documentId] = doc;
});
note the ()
at the end of the viewModel.documents()
, and how you have used correctly the viewModel.selectedDocumentIds()
in the ko.utils.arrayMap
.
Your fixed JSFiddle.
来源:https://stackoverflow.com/questions/16307483/observable-arrays-with-knockout-publishing-subscribing