带有组合框的Knockout可变长度列表的ASP.NET-如何绑定? [英] ASP.NET with Knockout variable length list with combobox - how to bind?

查看:84
本文介绍了带有组合框的Knockout可变长度列表的ASP.NET-如何绑定?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用以下ASP.NET模型

With the following ASP.NET models

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对象发送到适当的视图,我在视图中具有以下剔除定义:

Filling it out with dummy data and sending to appropriate view as User object, I have the following knockout definitions in the view:

@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>

最后是实际上应该处理如下所示的可变长度列表的编辑器模板:

And finally the editor template that is actually supposed to take care of variable length list that look like this:

@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. 无法使其在EditorTemplate组合框中起作用(或 下拉列表).无论我做什么,它都不会附加到标签"上.如果我 将其放在模板之外的其他地方-可以按预期工作.
  2. 此外,根据选择,在电子邮件中填写"SelectedValue"-操作方法.

  1. cannot make it work in the EditorTemplate for combobox (or dropdownlist). It won't attach to Labels no matter what I do. If I take it outside the template somewhere else - it works as expected.
  2. Also, based on selection to fill out the "SelectedValue" inside the Email - how to do that.

选择所有内容后,(这必须很简单)如何发布 在不损失任何价值的情况下全力以赴(它是一个超级嵌套模型 如您所见).

After everything is selected, (this must be simple) how to post it all back without losing values on the way (its a super nested model as you see).

非常感谢您!

推荐答案

标签位于您的视图模型上,而不是每封电子邮件中.由于模板是在Knockout foreach绑定的上下文中呈现的,因此绑定上下文已更改为电子邮件.

Labels is on your view model, not each email. Since the template is rendered within the context of a Knockout foreach binding, the binding context has changed to an email.

这是我写你的观点的方式:

Here's how I'd write your view:

@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中:我们需要告知Knockout使用$ root(您的视图模型),因为Labels实际上在您的视图模型中,而不是在单个电子邮件中.

The fix is in $root.Labels: we need to tell Knockout to use $root (your view model), since Labels is actually on your view model, and not on an individual email.

还要注意,我没有使用命名模板.这是优选的.除非您在视图中的多个位置使用模板,否则应使用匿名的内联模板,就像我在上面所做的那样.

Also notice I didn't use an named template. This is preferable. Unless you are using the template in more than one place in your view, you should use anonymous, inline templates like I did above.

这篇关于带有组合框的Knockout可变长度列表的ASP.NET-如何绑定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆