级联Telerik组合框在客户端数据绑定后记住选定的值

时间:2012-01-11 19:20:28

标签: c# javascript asp.net-mvc data-binding telerik-mvc

我的MVC视图中有两个组合框和一个网格:

<div id="Products" class="products maintField">
    @Html.Label("something", "Product:")
    @(Html.Telerik().ComboBox().Name("productList")
                               .AutoFill(true)
                               .DataBinding(c => c.Ajax().Select("GetProducts", "Maintenance").Enabled(true).Cache(true))
                               .Filterable(c => c.FilterMode(AutoCompleteFilterMode.StartsWith).Enabled(true))
                               .HighlightFirstMatch(true)
                               .ClientEvents(eb =>
                               {
                                   eb.OnChange("productChanged");
                               })
    )
</div>
<div id="Layouts" class="layout maintField">
    @Html.Label("something", "Layout:")
    @(Html.Telerik().ComboBox().Name("layoutList")
                               .ClientEvents(eb =>
                               {
                                   eb.OnChange("layoutChanged");
                               })
    )
</div>
<div style="clear: both;"/>
<div class="fields">
    @(Html.Telerik().Grid<MaintenanceModel>().Name("fieldList")
        .DataBinding(bc =>
        {
            bc.Ajax().Select("GetProductFields", "Maintenance", new { prodID = 0, layoutID = 0 }).Enabled(true);
        })
        .ClientEvents(c =>
        {
            c.OnDataBound("fieldGridBound");  
        })
        .Columns(c =>
        {
            c.Bound(mm => mm.Field_ID).ClientTemplate("<input id='Field_ID_<#= Field_ID #>' type='checkbox' name='checkedRecords' class=\"checkBoxGroup\" value='<#= Field_ID #>' />")
                                      .Title("<input id='mastercheckbox' type='checkbox' style='display:none;' />")
                                      .HeaderHtmlAttributes(new { style = "text-align: center;" })
                                      .Width(36)
                                      .HtmlAttributes(new { style = "text-align:center" });
            c.Bound(fld => fld.Field_Name).Title("Field Name").Width(225);
            c.Bound(fld => fld.Field_Description).Title("Field Description");
        }).Scrollable(c =>
        {
            c.Enabled(true);
            c.Height(700);
        }).Footer(false).Sortable(c =>
        {
            c.Enabled(false);
            c.OrderBy(oc =>
            {
                oc.Add(fld => fld.SeqNbr);
            });
        })
    )
</div>

对于一些不太漂亮的JS,组合框级联并最终填充网格:

function productChanged(e) {
    clearLayout();
    var layoutCombo = $("#layoutList").data('tComboBox');

    if (layoutCombo == null) {
        alert("Can't find layoutList");
        return;
    }

    if (e.value == "" || e.value == null) {
        clearLayout();
        return;
    }

    layoutCombo.loader.showBusy();
    $.get('@Url.Action("GetProductLayouts", "Maintenance")', { prodID: e.value }, function (result) {
        layoutCombo.dataBind(result);
        layoutCombo.loader.hideBusy();
    });
}
function layoutChanged(e) {
    var prodCombo = $("#productList").data('tComboBox');
    var fieldGrid = $("#fieldList").data('tGrid');

    if (fieldGrid == null) {
        alert("Can't find fieldList");
    }
    if (prodCombo == null) {
        alert("Can't find prodCombo");
    }

    if (e.value == "" || e.value == null) {
        clearGrid();
        return;
    }

    fieldGrid.rebind({ prodID: prodCombo.value(), layoutID: e.value });
    $("#mastercheckbox").css("display", "block");
}
function fieldGridBound(e) {
    var prodCombo = $("#productList").data('tComboBox');
    var layoutCombo = $("#layoutList").data('tComboBox');

    $.get('@Url.Action("GetLayoutFields", "Maintenance")', { prodID: prodCombo.value(), layoutID: layoutCombo.value() }, function (result) {
        var cbGroup = $(".checkBoxGroup");

        $(cbGroup).each(function (i, e) {
            if (result.indexOf(e.value) >= 0) {
                $(e).attr('checked', 'checked');
            } else {
                $(e).removeAttr('checked');
            }
        });
    });
}

除了填充两个组合框,绑定网格以及用户从第一个组合框中选择不同的值之外,这种方式非常有效。第二个组合框按预期重新绑定,但如果绑定到组合框的值没有改变(位置或显示值)并且用户再次选择相同的项目,则更改事件不会被触发。

具体示例

在数据库中,我有一个产品和布局的层次结构:

 Product A
     Platinum Layout
     Gold Layout
     Silver Layout
 Product B
     Platinum Layout
     Gold Layout
     Silver Layout
 Product C
     Platinum Layout
     Silver Layout

场景1

  1. 用户从第一个下拉列表中选择“产品A”,导致第二个下拉列表中填充了白金,黄金和白银布局。
  2. 用户从第二个下拉列表中选择“Platinum Layout”,导致相关信息显示在网格中。
  3. 用户从第一个下拉列表中选择“产品B”,导致第二个下拉列表再次填充白金,黄金和白银布局。
  4. 用户再次从第二次下拉菜单中选择“白金版面布局”,但更改后的事件不会触发,因为组合框在回弹之前没有忘记从中选择的内容。
  5. 场景2

    1. 用户从第一个下拉列表中选择“产品A”,导致第二个下拉列表中填充了白金,黄金和白银布局。
    2. 用户从第二个下拉列表中选择“Platinum Layout”,导致相关信息显示在网格中。
    3. 用户从第一个下拉列表中选择“产品C”,导致第二个下拉列表再次填充白金,黄金和白银布局。
    4. 用户从第二个下拉列表中选择“Platinum Layout”,导致场景1的步骤4中描述的相同错误行为。
    5. 场景3

      1. 用户从第一个下拉列表中选择“产品A”,导致第二个下拉列表中填充了白金,黄金和白银布局。
      2. 用户从第二个下拉菜单中选择“银色布局”,导致相关信息显示在网格中。
      3. 用户从第一个下拉列表中选择“产品C”,导致第二个下拉列表中填充了白金和银色布局。
      4. 用户从第二个下拉菜单中选择“银色布局”,导致相关信息显示在网格中(在其他两个场景中应该如此)。
      5. 为了试图强制组合框忘记在反弹之前选择了哪个项目,我尝试在绑定之前手动将所选项目设置为-1(无):

          

        layoutCombo.select(-1);

        我也尝试使用

        在绑定后重新加载组合框
          

        layoutCombo.reload();

        然而,他们都没有为我工作。

        有没有其他人在类似情况下看到这种行为?有没有办法从我的页面中手动清除组合框的最后一个选定的项目变量(没有在Telerik源中挖掘)?

1 个答案:

答案 0 :(得分:1)

在玩了一点之后,希望它能正常工作,如果我在layoutCombo.select(-1)之后手动触发更改事件并且在第二个组合框上强制dataBind之前,它看起来是有效的。这是我的productChanged代码现在的样子:

function productChanged(e) {
    clearLayout();
    var layoutCombo = $("#layoutList").data('tComboBox');

    if (layoutCombo == null) {
        alert("Can't find layoutList");
        return;
    }

    if (e.value == "" || e.value == null) {
        clearLayout();
        return;
    }

    layoutCombo.loader.showBusy();
    $.get('@Url.Action("GetProductLayouts", "Maintenance")', { prodID: e.value }, function (result) {
        layoutCombo.select(-1);
        layoutCombo.trigger.change(); //**** Trigger the change manually so the combobox knows its value has changed
        layoutCombo.dataBind(result);
        layoutCombo.loader.hideBusy();
    });
    //layoutCombo.reload();
}

感觉有点像黑客,因为组合框应该已经知道它自己的价值了。任何其他想要使这个更清洁的想法将非常感激。