级联Telerik组合框在客户端数据绑定后记住选定的值
本文关键字:后记 数据绑定 组合 Telerik 客户端 级联 | 更新日期: 2023-09-27 18:19:58
我的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
- 用户从第一个下拉列表中选择"产品A",导致第二个下拉列表填充白金、金色和银色布局
- 用户从第二个下拉列表中选择"Platinum Layout",使相关信息显示在网格中
- 用户从第一个下拉列表中选择"产品B",导致第二个下拉列表再次填充白金、金色和银色布局
- 用户再次从第二个下拉框中选择"Platinum Layout",但更改后的事件没有启动,因为组合框没有忘记在反弹之前从中选择的内容
场景2
- 用户从第一个下拉列表中选择"产品A",导致第二个下拉列表填充白金、金色和银色布局
- 用户从第二个下拉列表中选择"Platinum Layout",使相关信息显示在网格中
- 用户从第一个下拉列表中选择"产品C",导致第二个下拉列表再次填充白金、金色和银色布局
- 用户从第二个下拉列表中选择"Platinum Layout",导致与场景1的步骤4中描述的相同错误行为
场景3
- 用户从第一个下拉列表中选择"产品A",导致第二个下拉列表填充白金、金色和银色布局
- 用户从第二个下拉菜单中选择"银色布局",使相关信息显示在网格中
- 用户从第一个下拉列表中选择"产品C",导致第二个下拉列表填充白金和银色布局
- 用户从第二个下拉列表中选择"Silver Layout",导致相关信息显示在网格中(在其他两个场景中应该发生的情况)
为了迫使组合框忘记在反弹之前选择了哪个项目,我尝试在绑定之前手动将选择的项目设置为-1(无),使用:
layout组合框。选择(-1);
我还尝试过在绑定后使用重新加载组合框
layoutCombo.reload();
然而,他们都不为我工作。
有没有其他人在类似的情况下看到过这种行为?有没有办法从我的页面中手动清除组合框最后一个选择的项目变量(而不需要在Telerik源中挖掘)?
在多玩了一点并希望它能正常工作之后,如果我在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();
}
这感觉有点像黑客,因为组合框应该已经知道它自己的价值了。如果有任何其他想法可以让这个地方更干净,我们将不胜感激。