Steve
Steve

Reputation: 70

Updating an element in a Knockout JS Observable Array

I've been reading this site and finally have a question that wasn't already answered specifically enough for my needs, so here goes.

I have an observable array created from a data array passed to my KO view model in a C# application.

    self.Stuff = ko.observableArray(data.Stuff);

This array doesn't have observable elements and there lies my problem. I need to edit an element (status) via an onclick. I know I need to either make the elements observable (not sure how with the data.Stuff portion) or do a "valueHasMutated" but I'm not entirely sure how that syntax would work.

Of course, my push and remove work fine since they trigger the arrayobservable and refresh the view.

    if ($form.valid() && isValidStuff) {
        self.Stuff.push({ ABC: self.ABCInput(), XYZ: self.XYZInput(), Status: self.StatusInput()});
        self.resetValues();
    }

    self.removeStuff = function () {
        self.Stuff.remove(this);
    };

    self.StuffStatusChng= function (){
        //What to do?
        self.Stuff.vauleHasMutated();
    };

Any help or push in the right direction would be a great help, thanks! If I don't have enough info, please let me know what I can provide.

Thanks,

Upvotes: 0

Views: 142

Answers (2)

John Lucas
John Lucas

Reputation: 1617

How about using the knockout mapping plugin:

http://knockoutjs.com/documentation/plugins-mapping.html

It has a fromJSON method that takes an array of json strings and makes an observable array with observable property for each property:

A fiddle can be found here: http://jsfiddle.net/jiggle/uzn7Z/, notice once bound, you can update the first name and it will update the property accordingly

HTML:

<div data-bind="foreach: people">
       <div>
           <input type="text" data-bind="value:firstName"/>
           <span data-bind="text: firstName"></span>
           <span data-bind="text: lastName"></span>
    </div>

</div>

Code:

var stuff = '[{"firstName":"fred","lastName":"bloggs"},{"firstName":"david","lastName":"frost"}]';

console.log(stuff);
var people = ko.mapping.fromJSON(stuff);
console.log(people());
var viewModel ={};

viewModel.people=people;

ko.applyBindings(viewModel);

Just need to download and include knockout.mapping.js.

Upvotes: 1

Hans Roerdinkholder
Hans Roerdinkholder

Reputation: 3000

Does this help you?

var OneStuff = function (data) {
    this.ABC = ko.observable(data.ABC);
    this.XYZ = ko.observable(data.XYZ);
    this.Status = ko.observable(data.Status);
};
self.Stuff = ko.observableArray(ko.utils.arrayMap(data.Stuff, function (oneStuffData) {
    return new OneStuff(oneStuffData);
}));

This will make the individual properties observable.

To push:

self.Stuff.push(new OneStuff({ ABC: self.ABCInput(), XYZ: self.XYZInput(), Status: self.StatusInput()}));

Upvotes: 0

Related Questions