Knockout视图模型部分回发到ASP.NET MVC - 如何回发完整的对象?

时间:2013-03-07 14:39:13

标签: asp.net-mvc knockout.js viewmodel knockout-2.0 asp.net-mvc-viewmodel

拥有这些ASP.NET MVC视图模型:

public class User
  {
    public string Name { get; set; }
    public LabeledEmail LabeledEmail { get; set; }
  }
public class LabeledEmail
  {
    public IList<ContactLabel> Labels;
    public IList<ContactEmail> Emails;
  }

和Knockout视图模型如下:

  <script type="text/javascript">

    $(function() {
      ko.applyBindings(viewModel);

      $("#profileEditorForm").validate({
    submitHandler: function(form) {
      if (viewModel.save())
        window.location.href = "/";
      return false;
    }
      });
    });

    var viewModel = {

      Name: ko.observable("@Model.Name"),

      EmailLabels: ko.observableArray(@Html.Json(Model.LabeledEmail.Labels.Select(l => l.Name)) || []),
      Emails: ko.observableArray(@Html.Json(Model.LabeledEmail.Emails) || []),

      addEmail: function() {
    viewModel.Emails.push(@Html.Json(new ContactEmail()));
      },
      removeEmail: function(eml) {
    viewModel.Emails.remove(eml);
      },

      saveFailed: ko.observable(false),

      // Returns true if successful
      save: function() {
    var saveSuccess = false;
    viewModel.saveFailed(false);

    jQuery.ajax({
      type: "POST",
      url: "@Url.Action("MyAction", "MyController")",
      data: ko.toJSON(viewModel),
      dataType: "json",
      contentType: "application/json",
      success: function(returnedData) {
        saveSuccess = returnedData.Success || false;
        viewModel.saveFailed(!saveSuccess);
      },
      async: false
    });     
    return saveSuccess;
      }
    };
</script>

回复到控制器的帖子是User.Name,但User.LabeledEmail为空。 我必须按照我的方式压扁模型,以便能够在其他地方单独使用列表。 我知道viewModel.Emails在保存时已正确填充,但User.LabeledEmails以某种方式返回null。

它基本上归结为分配Model.LabeledEmail.Emails viewModel.Emails并且交易将会解决,但似乎我不知道如何找到任何合适的例子。

  1. 我犯的错误是什么,
  2. 怎么做得好?
  3. 提前谢谢。

1 个答案:

答案 0 :(得分:3)

您的JSON数据结构应该与C#类的结构匹配,尤其是属性名称。所以你需要发送一个看起来像这样的JSON:

{
    Name: 'somename',
    LabeledEmail: {
        Labels: [ somelements ],
        Emails: [ someelements ]
    }
}

所以改变你的data: ko.toJSON(viewModel),

data: JSON.stringify({
   Name: viewModel.Name(),
   LabeledEmail: { 
       Labels: viewModel.EmailLabels(),
       Emails: viewModel.Emails()
   }
})

或者只是在客户端和服务器上使用相同结构的数据......

作为旁注:您的C#视图模型需要具有属性而不是字段才能使MVC模型绑定器正常工作:

public class User
{
    public string Name { get; set; }
    public LabeledEmail LabeledEmail { get; set; }
}

public class LabeledEmail
{
    public IList<ContactLabel> Labels { get; set; }
    public IList<ContactEmail> Emails { get; set; }
}