Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 248
patryk Avatar asked Jul 29 '13 13:07

patryk


2 Answers

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.

like image 174
Damien Avatar answered Oct 11 '22 07:10

Damien


I suggest use copy

so you can provide array of the properties you want to not be observables.

var mappingPeople = {
    'copy': ["name"]
};

var mapping = {
    create: function (opts) {
        return ko.mapping.fromJS(opts.data, mappingPeople);
    }
};
var PeopleArr = ko.mapping.fromJS(people, mapping);

here is Working Demo

Update

In case you need to mark one property as observable and the rest 'll be normal properties then i suggest to use observe.

here is an update to my Example using observe

like image 38
ebram khalil Avatar answered Oct 11 '22 08:10

ebram khalil