【问题标题】:Cascading Telerik combo boxes remember selected value after client side databinding级联 Telerik 组合框在客户端数据绑定后记住选定的值
【发布时间】:2012-01-11 19:20:28
【问题描述】:

我的 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. 用户从第二个下拉菜单中选择“白金版式”,导致相关信息显示在网格中。
  3. 用户从第一个下拉菜单中选择“产品 B”,导致第二个下拉菜单再次填充白金、黄金和白银布局。
  4. 用户再次从第二个下拉菜单中选择“Platinum Layout”,但不会触发 changed 事件,因为组合框在反弹之前没有忘记选择的内容。

场景 2

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

场景 3

  1. 用户从第一个下拉菜单中选择“产品 A”,导致第二个下拉菜单填充白金、黄金和白银布局。
  2. 用户从第二个下拉菜单中选择“银色布局”,导致相关信息显示在网格中。
  3. 用户从第一个下拉菜单中选择“产品 C”,导致第二个下拉菜单填充白金和白银布局。
  4. 用户从第二个下拉菜单中选择“银色布局”,导致相关信息显示在网格中(在其他 2 个场景中应该会发生)。

为了尝试强制组合框在被反弹之前忘记选择了哪个项目,我尝试在绑定之前手动将所选项目设置为 -1(无):

layoutCombo.select(-1);

我也尝试在绑定后重新加载组合框

layoutCombo.reload();

但是它们都不适合我。

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

【问题讨论】:

  • 你是怎么输入这么多文字的:-o。我希望你也把这个发布到 Telerik 论坛。
  • 在提出问题时,请务必彻底,以便能够帮助您的人获得他们需要的所有信息。此外,没有代码块的文本也不是那么多

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


【解决方案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();
}

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

【讨论】:

    猜你喜欢
    • 2011-10-27
    • 1970-01-01
    • 1970-01-01
    • 2011-12-09
    • 2015-06-13
    • 1970-01-01
    • 2012-03-20
    • 2011-03-24
    • 1970-01-01
    相关资源
    最近更新 更多