【问题标题】:Knockout view model posts back to ASP.NET MVC partially - how to post back complete object?淘汰视图模型部分回发到 ASP.NET MVC - 如何回发完整对象?
【发布时间】:2013-03-07 14:39:13
【问题描述】:

拥有这些 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. 如何正确操作?

提前谢谢你。

【问题讨论】:

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


    【解决方案1】:

    您的 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; }
    }
    

    【讨论】:

    • 谢谢。我尝试了这种方法(使用不同的 KO 视图模型)。如果我这样做,我无法在我的视图中呈现标签和电子邮件(在我的另一个问题中回答)。我正在构建类似于 gmail 新联系人的 smth - 你有 [work|home|etc] 标签和 [email|phone|address|etc] - 不能在使用敲除的可变长度列表中以这种方式使用它们。我认为我需要以某种方式将表单中填写的内容“组合”回视图模型。按照您的建议更改视图模型将杀死到目前为止构建的功能。希望你能理解我的思想流派。谢谢
    • 我不关注你。如果您按照我所展示的那样构建data:,则无需在服务器或客户端更改类结构的任何内容,它应该可以工作(并且如果您在C#端使用属性)...
    • 1.将 C# 更改为属性(很好的观察!谢谢) 2. 我应该将 ko.Email 和 ko.EmailLabels 留在 ko 的根级别,对吗? 3. 只需要返回你显示的方式而不是我的 toJSON(vm) 东西,对吧?我有没有准确地跟着你? (因为到目前为止,它甚至会破坏视图并且甚至无法正确渲染,即使我确实发送了您描述的 Json)。这一切都说得通,但不幸的是不起作用。我想我需要一些时间来弄清楚为什么……
    • 关键是您可以拥有适合您的服务器端的 C# 和适合您的 UI 和绑定的 KO 视图模型。但是当您想将数据发送回服务器时,您需要在两种形式之间进行转换。所以你的jQuery.ajax 数据应该与 C# 视图模型的结构相匹配...
    • 这在将视图模型传递回控制器时起作用(在我制定了细节之后)。所以你得到了你的正确答案v标记+“答案很有用”投票 - 非常感谢你!然而,Q-n - ModelState.IsValid 变成了 false 并且不知道为什么。是因为我正在手动编译回发对象吗?再次感谢
    猜你喜欢
    • 2014-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-13
    • 2016-08-06
    相关资源
    最近更新 更多