2

我正在尝试使用 knockout.js 获得四个级联下拉列表:

  1. 搜索条件
  2. 子标准
  3. 价值
  4. 状态

通过使用以下链接中的代码,我能够获得第一个级联(但由于数据绑定问题而不是其他级联):

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 代码的以下部分:

  1. 我在这个模板中为其他两个下拉菜单指定了什么。例如,第三个下拉列表需要绑定到 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>
    
  2. 这个对吗?

    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));
    

    };

  3. 如何将完整的 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);
    
  4. 这里有什么需要更改的绑定吗?

    // 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 类。

4

2 回答 2

0

我不确定我是否完全理解你的问题,但无论如何我都会尝试一下:)。我认为您正在寻找一种“验证”的方法,如果实际上是时候允许下一个下拉菜单处于活动状态?

如果是这样,您可以从Computed Observables的角度来处理它。基本上,您会将每个下拉列表绑定到从先前依赖项派生的计算值。

让我写小提琴,我会告诉你:)

好的,试一试……抱歉耽搁了…… http://jsfiddle.net/farina/ZNBcM/3/

于 2012-02-27T21:17:34.030 回答
0

我更新了答案,希望,它会帮助新来的人。在 MVC 中使用 Knockout JS 绑定分层下拉列表的方法

在这里你可以找到很好的例子。

于 2015-06-19T07:01:02.733 回答