1

これらの 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;
  }

ノックアウト ビュー モデルは次のようになります。

  <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.NameUser.LabeledEmail空です。別の場所でリストを個別に使用できるようにするには、モデルをフラット化する必要があります。実際、保存中にviewModel.Emailsが適切に入力されることは知っていますが、User.LabeledEmailsはどういうわけかnullを返します。

それは基本的に を割り当てることModel.LabeledEmail.EmailsviewModel.Emailsなり、取引は解決されるようですが、方法がわからず、適切な例が見つかりません。

  1. 私が犯す過ちとは
  2. 適切に行う方法は?

前もって感謝します。

4

1 に答える 1

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()
   }
})

または、クライアントとサーバーの両方で同じ構造のデータを使用するだけです...

補足として: MVC モデル バインダーが正しく機能するためには、C# ビューモデルにフィールドではなくプロパティが必要です。

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; }
}
于 2013-03-07T15:05:21.157 に答える