coderenaissance / knockout.viewmodel

The knockout viewmodel plugin is the fastest, smallest, cleanest, most flexible way to create a knockout viewmodel.
http://coderenaissance.github.com/knockout.viewmodel
105 stars 27 forks source link

updateFromModel not mapping nested properties into observables #37

Open ClearCloud8 opened 11 years ago

ClearCloud8 commented 11 years ago

When my page loads I have a viewModel with two properties on it. One is set to an empty array. The other is set to null, because once it is populated it will not be an array. This (essentially empty) viewModel is immediately bound to the HTML using ko.applyBindings when the page loads.

Later, the user will click the search button which will update portions of my viewModel.

I am experiencing a problem at this stage. The array gets updated just fine using "updateFromModel". However, the non-array property I am trying to update using "updateFromModel".... fails to be mapped properly.

The object literal I am passing in gets mapped into an observable correctly.... but NONE of its nested properties get mapped to observables themselves. Here is a jsFiddle demonstrating the issue. (When you click the button, the blue box does not get populated with the employee name.)

http://jsfiddle.net/abJCQ/1/

If I try to start off the problematic property as {} instead of null in the very beginning, the issue is even worse. (the entire property is not mapped to observable)

coderenaissance commented 11 years ago

You are right, nullable objects are an issue. I'm working on the fix for this now and it will be in the next release. In the mean time the only workaround is to either not return nulls or call ko.viewmodel.fromModel on employeed before calling updateFromModel.

You only have to work around this if you need to observe the changes to the properties. Binding to non observable properties works fine unless you need to respond to changes (hence the need for observables). The value binding will update the changes to your non observable properties without a problem. http://jsfiddle.net/mX7sN/

As a side note, there is a problem with the bindings in your current code will get your updated data displaying. In your current code there is another problem with your bindings that needs to be fixed, which is why nothing shows up. Because Employee is initially a null it gets wrapped in an observable. When it gets updated the new value (object) gets stuffed into the observable. So your if binding should be if:employee() which would be falsy if employee() === null. Also your other bindings off of employee need to use parens e.g. employee().fullName. This will get your data showing up. http://jsfiddle.net/cNUZL/1/embedded/result/

ClearCloud8 commented 11 years ago

Thanks for the response. You are correct about my bindings being messed up... for some reason I was thinking that I wouldn't need the () in "employee().fullName" when writing a binding in the HTML. I thought with.... text: employee.fullName..... KO would be able to traverse down to the nested property, regardless of the fact that employee is observable or not. So that was a failure in my understanding of writing out the bindings in HTML.

In regard to the nullable objects situation... I was testing to compare behavior between what I could do in viewModel plugin versus ko.mapping. Here is what I want to do (and am able to do) using ko.mapping. I am able to start with a null value in employee and then populate the object.... and all the properties of the employee object become observable. Here is the working example: http://jsfiddle.net/HE7XN/

When I run the example we already talked about using viewModel plugin.... http://jsfiddle.net/cNUZL/1/ .... then all the properties on employee are not made observable after the update.

Temporary work around: I think what I can do in the meantime is make an AJAX call out to the server to return an empty instance of my employee class. This way at least the automatic mapping can still occur and my viewModel can have a semi-empty starting state. It's not ideal, but I think it will work for the time being.

I look forward to your code update on this, when you have time. :-) Although ko.mapping is working the way I want it to.... i like your syntax much better. It is easier to look at.... plus the fact that your plugin runs much faster... I am particularly eager to take advantage of that since a lot of my users are stuck with older browsers and any speed improvement can help.

oexza commented 10 years ago

when is the next release coming? cos issues like this need to be fixed desperately as i'm encountering very similar problems

acornejo commented 10 years ago

same here. had the same issue with knockout mappings and hoped knockout.viewmodel would work.