0

次の ASP.NET モデルを使用

public class User
  {
    public string Name { get; set; }
    public LEmail LEmail { get; set; }
  }
public class LEmail
  {
    public IList<CLabel> Labels;
    public IList<CEmail> Emails;
  }
public class CLabels
  {
    public IList<CLabel> Labels { get; set; }
  }
public class CLabel
  {
    public string Name { get; set; }
  }
public abstract class CEmail
  {
    public string SelectedLabel { get; set; }
    public string Name { get; set; }
  }

ダミー データを入力し、適切なビューにUserオブジェクトとして送信すると、ビューに次のノックアウト定義があります。

@using (Html.BeginForm("MyAction", "MyController", FormMethod.Post, new { id = "MyEditor" }))
{
  @Html.EditorFor(m => @Model.LEmail)
 <p>
    <input type="submit" value="Save" data-bind="enable: Emails().length > 0" />
    <a href="/">Cancel</a>
  </p>

  <p data-bind="visible: saveFailed" class="error">A problem occurred saving the data.</p>

  <div id="debug" style="clear: both">
    <hr />
    <h2>Debug:</h2>
    <div data-bind="text: ko.toJSON(viewModel)"></div>
  </div>
}

<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"),

    Labels: ko.observableArray(@Html.Json(Model.LEmail.Labels) || []),
    Emails: ko.observableArray(@Html.Json(Model.LEmail.Emails) || []),
    addEmail: function() {
      viewModel.Emails.push(@Html.Json(new CEmail()));
    },
    removeEmail: function(eml) {
      viewModel.Emails.remove(eml);
    },

    saveFailed: ko.observable(false),

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

      // Executed synchronously for simplicity
      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>

そして最後に、実際に次のような可変長リストを処理することになっているエディター テンプレート:

@model MyDomain.ViewModels.LEmail

<table>
    <tbody data-bind="template: { name: 'EmailsTemplate', foreach: Emails }" />
</table>

<button data-bind="click: addEmail">Add Email</button>

<script id="EmailsTemplate" type="text/html">
      <tr>
        <td>
      @* PROBLEM IS HERE!! Labels won't show (they will it this code taken out of template) *@
           <select data-bind="options: Labels"></select></td>
        <td>
          <input type="text" data-bind="value: Name, uniqueName: true" class="required" /></td>
        <td>
          <a href="#" data-bind="click: function() { viewModel.removeEmail(this); }">Delete</a></td>
      </tr>
</script>

本質的に私は

  1. EditorTemplateforコンボボックス(またはドロップダウンリスト)で機能させることはできません。何をしてもラベルに付けられません。テンプレートの外にある別の場所に移動すると、期待どおりに機能します。
  2. また、選択に基づいて、電子メール内の「SelectedValue」に入力します - その方法。

  3. すべてが選択された後 (これは単純なはずです)、途中で値を失うことなくすべてを元に戻す方法 (ご覧のとおり、スーパー ネスト モデル)。

事前にどうもありがとうございました!

4

1 に答える 1

1

ラベルは、各メールではなく、ビュー モデルにあります。テンプレートは Knockout foreach バインディングのコンテキスト内でレンダリングされるため、バインディング コンテキストは電子メールに変更されました。

これが私があなたの見解を書く方法です:

@model FiveW.ViewModels.LabeledEmail

<table>
    <tbody data-bind="foreach: Emails">
        <tr>
           <td>
              <select data-bind="options: $root.Labels, value: SelectedLabel"></select>
           </td>
           <td>
              <input type="text" data-bind="value: Name, uniqueName: true" class="required" />
           </td>
           <td>
              <a href="#" data-bind="click: function() { viewModel.removeEmail(this); }">Delete</a>
           </td>
      </tr>
    </tbody>
</table>

<button data-bind="click: addEmail">Add Labeled Email</button>

修正は $root.Labels にあります: $root (ビュー モデル) を使用するよう Knockout に指示する必要があります。Labels は実際にはビュー モデルにあり、個々の電子メールにはありません。

また、名前付きテンプレートを使用していないことにも注意してください。これは好ましいことです。ビュー内の複数の場所でテンプレートを使用していない限り、上記のように匿名のインライン テンプレートを使用する必要があります。

于 2013-03-06T23:21:22.183 に答える