Knockout subscribe to observable object

2019-05-14 03:34发布

问题:

I have an object:

{ model: settings: { "FirstName": "Joe", "LastName": "Bloggs" } };

in my view model I make settings an observable:

this.Settings = ko.observable(ko.mapping.fromJS(model.settings));

Which makes FirstName and LastName observables too.

In my view I bind by doing:

<p data-bind="text: Settings().FirstName"></p>

to read a value from Settings I do:

`this.Settings().FirstName()`

The problem comes in when I want to subscribe when FirstName OR LastName changes.

I know I can do this.Settings.FirstName.subscribe... but that's painful once you get more than two things you're observing.

Is there a way to do this.Settings.subscribe...? or should I be using a custom binding?

回答1:

I wrote the plugin below to help me deal with such situations:

https://github.com/ZiadJ/knockoutjs-reactor

Here's a simple usage example:

 this.Settings.watch(function(root, trigger){
     var newValue = trigger();
 });


回答2:

By using, computed observables, you can automatically update whenever any of these dependencies changes. For example, FullName will get updated when either Firstname or LastName changed.

 this.Settings().FullName =  ko.computed(function() {
    return this.Settings().FirstName() + " " + this.Settings().LastName();
});

borrowed from KnokcoutJS.com

Note: I will work little more to make viewmodel little cleaner.



回答3:

You should try the mapping plugin, which lets you take plain JSON objects and convert them to full view models.

Basically it converts every member on each object into an observable:

var data = { "FirstName": "Joe", "LastName": "Bloggs" };
var viewModel = ko.mapping.fromJS(data);

Then you could bind this viewmodel to your html a bind properties straightaway like this:

<p data-bind="text: FirstName"></p>

This is a small example, I only mapped a plain object, but you can also achieve more complex mappings if you wanted to convert nested objects like the one in your example. There is more information about this on the documentation.



标签: knockout.js