Search code examples
javascriptknockout.jsknockout-mapping-plugin

Turn certain observableArray objects properties into observable


Say I have this array of same-type objects:

var people = [
    { status: 0, name: "name1"},
    { status: 1, name: "name2"}
];

and I want it not only to be observableArray, but also I want to observe ONLY, say, status property of each object.

Imagine that the objects themselves might be added or deleted. The name property of any of those objects is not going to change so I don't really need to observe the name but the status of every object might get changed, thus it'd be cool to make it observable.

Is it possible to map it with knockout utilities with some cool hack syntax or do I have to either iterate through every object and map its status property into observable or have the whole array and its objects properties observable?


Solution

  • You can use ko.mapping.fromJS

    var vm = ko.mapping.fromJS(people,{
        create: function(options){    
            return {
                status : ko.observable(options.data.status), // observable
                name: options.data.name, // non observable
            }
        }
    });
    

    Now vm is an observableArray that contains objects in which status is an obsevable and name is a regular property.

    See fiddle

    @Patryk :

    You could do that, if you have many properties and you want to convert only one into observable.

    var o = ko.mapping.fromJS(people,{create: function(options){
        // clone item
        var item = ko.utils.extend(options.data, {});
        // replace status property by an observable 
        item.status = ko.observable(options.data.status);
        return item;
    }});
    

    See updated fiddle

    You could also use observe with mapping parameter

    var mapping = {
        create: function (options) {
            return ko.mapping.fromJS(options.data, {'observe': ["status"]});
        }
    };
    var o = ko.mapping.fromJS(people, mapping);
    

    See fiddle

    I hope it helps.