AndreyAkinshin / knockout-mvc

Power of Knockout.js for ASP.NET MVC
http://knockoutmvc.com
203 stars 125 forks source link

data-bind attribute for Nested object is invalid #12

Open penfold opened 11 years ago

penfold commented 11 years ago

For the following JSON:

{"ParentTitle":"Fred","Belongings":{"Title":"My stuff","Things":[{"Description":"Shoe","Amount":123},{"Description":"Hat","Amount":456}],"Summary":"I have lots"}}

The 'Belongings' object is a nested object (and not an array). The ko.mapping.fromJS(viewModelJs) does not make the Belongings object an observable so it's properties should be accessed as:

Belongings.Title

but the ko.Html.TextBox (and the ForEach functionality) create:

Belongings().Title

This then causes an exception in the call to:

ko.applyBindings(viewModel);

because it can't find Belongings().Title

I've manually created html without the () and the bindings work correctly.

Is it possible to fix do a urgent fix for this problem?

Thanks, P

penfold commented 11 years ago

I've made a change in my local copy of the code at:

KnockoutExpressionConverter.VisitMemberAccess(...)

and changed:

string suffix = member == "length" ? "" : "()";

to

string suffix = "";

These seems to resolve the problem. But due to the complexity of the ExpressionConverter, I'm unsure of the impact of this change in other senerios.

Thanks, P

ivan-sam commented 11 years ago

Adding a couple of lines marked with "++" below I've made all project tests done (I've changed tests with nested binding though).

KnockoutExpressionConverter.cs

//TODO: rewrite
private string VisitMemberAccess(Expression obj, string member)
{      
  // ......

  if ((member == "Length" || member == "Count") && !data.InstanceNames.Contains(own))
    member = "length";

++ if (obj is MemberExpression && member != "length") ++ own = GetterSetterCorrecting(own);

  string prefix = own == "" ? "" : own + ".";

  // ......