user2501886
user2501886

Reputation:

Knockout mapping plugin [create, update]: objects created, cannot update

I've posted my code here: http://jsfiddle.net/HYDU6/6/ It's a pretty stripped-down version of what I'm actually working with, but captures the essence of my problem. My view model is like so:

var viewModel = {
    objects: {
        foo: [
            { text: "Foo's initial" },
        ],
        bar: [
            { text: "Bar's initial" },
        ]
    }
}

I'm using the ko.mapping plugin and my create handler for objects instantiates Obj from objects.foo and then objects.bar, returning the resulting two items in an array. This part works fine; I use

var view = {};
ko.mapping.fromJS(viewModel, mapping, view);

My issue is updating based on new data. (i.e., getting data from the server). I have an object of new data and I attempt

ko.mapping.fromJS(new_model, mapping, view);

I suspect this is incorrect but I have not been able to get it working despite extensive searching. (Trust me, it's been days. ): Anyway, thanks for any help.

EDIT: So I've mostly figured it out - I was depending too heavily on mapping.fromJS and certain things were not being wrapped into observables. I also realized that I didn't need the create(), only the update(), as it is called after create() anyway. If you have a similar problem let me know!

Upvotes: 3

Views: 1341

Answers (1)

Ryan Rahlf
Ryan Rahlf

Reputation: 1812

John,

When updating your data using ko.mapping be sure you don't create a new item. Your UI is already bound to the existing items, so you just want to update the values of the existing item properties; not create new ones. For the example you posted, you'll want to adjust your "update" method of your map to insert the new values into the correct ko.observable property, rather than creating a new object in it's place. The ko.mapping "update" method has a few different parameter lists depending on usage, with the third parameter being the target object of the map. You would want to update that object's properties.

obj.target[label].items[0].text(obj.data[label][0].text);

But, that's a bit of a mess. You'll probably want to create a second level of mappings (create / update) to handle "deep" object hierarchies like in your fiddle. For example one map for objects at the "foo/bar" level, and another call to ko.fromJS from within "update" with another map for the child Obj() objects.

After fixing that, you'll run into a couple simple binding errors that you can fix using another "with" binding, or a "foreach" binding for the child arrays.

Overall, you've just run into a couple common pitfalls, but nothing too severe. You can learn a bit more about a few of these pitfalls on my blog here : http://ryanrahlf.com/getting-started-with-knockout-js-3-things-to-know-on-day-one/

I hope this helps!

Upvotes: 4

Related Questions