我正在尝试使用 knockout.js 获得四个级联下拉列表:
- 搜索条件
- 子标准
- 价值
- 状态
通过使用以下链接中的代码,我能够获得第一个级联(但由于数据绑定问题而不是其他级联):
http://blogs.msdn.com/b/thebeebs/archive/2011/12/01/price-calculator.aspx
这些下拉列表的数据将作为 SearchCriterion 的 IEnumrable 从使用 ViewBag.CriteriaData 变量的 MVC 视图返回到我的剃须刀视图页面。我的类的代码如下:
public class SearchCriterion
{
public string Text { get; set; }
public string Value { get; set; }
public List<SubCriterion> SubCriteria { get; set; }
}
public class SubCriterion
{
public string SearchCriterionValue { get; set; }
public string Text { get; set; }
public string Value { get; set; }
public List<ColumnValue> ColumnValues { get; set; }
}
public class ColumnValue
{
public string SearchCriterionValue { get; set; }
public string SubCriterionValue { get; set; }
public string Text { get; set; }
public string Value { get; set; }
public IEnumerable<StateValue> StateValues { get; set; }
}
public class StateValue
{
public string SearchCriterionValue { get; set; }
public string SubCriterionValue { get; set; }
public string ColumnValue { get; set; }
public IEnumerable<int> InputStateIds { get; set; }
public IEnumerable<int> OutputStateIds { get; set; }
public int SelectedInputStateId { get; set; }
public int SelectedOutputStateId { get; set; }
public string Text { get; set; }
public string Value { get; set; }
}
我面临的问题在 .cshtml 代码的以下部分:
我在这个模板中为其他两个下拉菜单指定了什么。例如,第三个下拉列表需要绑定到 ColumnValue.Value(ColumnValue 是 SubCriterion 的一部分)
<script id='criteriaRowTemplate' type='text/html'> <tr> <td><select data-bind='options: criteriaData, optionsText: "Text", optionsCaption: "Search Criterion", value: SearchCriterion' /></td> <td><select data-bind='visible: SearchCriterion, options: SearchCriterion() ? SearchCriterion().SubCriteria : null, optionsText: "Text", optionsCaption: "Sub Criterion", value: SubCriterion' /></td> <td><select data-bind='visible: SubCriterion, options: SubCriterion() ? SubCriterion().ColumnValues : null, optionsText: "Text", optionsCaption: "Column Value", value: ColumnValue'/></td> <td><select data-bind='visible: ColumnValue, options: ColumnValue() ? ColumnValue().StateValues : null, optionsText: "Text", optionsCaption: "State", value: StateValue'/></td> <td><button data-bind='click: function() { viewModel.removeLine($data) }'>Remove</button></td> </tr> </script>
这个对吗?
var CriteriaLine = function() { this.SearchCriterion = ko.observable(); this.SubCriterion = ko.observable(); this.ColumnValue = ko.observable(); this.StateValue = ko.observable(); // Whenever the Search Criteria changes, reset the Sub Criteria selection this.SearchCriterion.subscribe(function() { this.SubCriterion(undefined); }.bind(this)); this.SubCriterion.subscribe(function() { this.ColumnValue(undefined); }.bind(this)); this.ColumnValue.subscribe(function() { this.StateValue(undefined); }.bind(this));
};
如何将完整的 C# 对象与 Javascript 对象映射?如果我们只有前两个下拉菜单,它就可以工作:
// Create a Javascript object object with the same property names as the C# object var dataToSearch = $.map(this.lines(), function (line) { return line.StateValue() ? line.StateValue() : undefined; }); var SearchObject = new function () { this.StateValues = dataToSearch; }; // Convert the object to JSON var searchCriteria = JSON.stringify(SearchObject);
这里有什么需要更改的绑定吗?
// Apply the data from the server to the variable var criteriaData = @Html.Raw(@Json.Encode(ViewBag.CriteriaData)); var viewModel = new Criteria(); ko.applyBindings(viewModel, document.getElementById("criteriaDiv"));
编辑:
我现在可以填充级联下拉列表(上面更新了代码)。现在我有 4 列,每列都有一个下拉列表。我还使用 Knockoutjs 动态添加了 1...n 行。因此,用户现在可以从这些下拉列表中选择值,并根据需要添加更多行下拉列表。剩下的唯一事情是将用户为下拉菜单选择的值返回给控制器(上面的第 3 点)。我不确定我该怎么做。任何帮助,将不胜感激。
编辑2:
为第 3 项添加了工作代码并修改了 ColumnValue 和 StateValue 类。