我有一个场景,我可以访问 Select 控件(组合框),并且我需要一种在其源/选项列表更改时触发事件的方法。
例如,如果我有一个选择控件,它首先将 Option1 和 Option2 作为其选项,我需要一种在选项更改为 Option1、Option3、Option4 时触发事件的方法。我不在乎是否添加、删除了新选项,或者是否新添加了所有项目。All I want is a event handler when the options of a select control change.
一位朋友建议在将 Option 元素添加到 DOM 时更改 DOM,但我不确定这是因为每次页面中的任何 dom 元素更改时都会触发 DOM 更改。
更新:很抱歉造成混乱。我不是在寻找选择更改。我正在寻找实际选项列表的更改。
我正在使用 Knockoutjs,并且我将一个可观察数组作为选项绑定到一个选择控件。knockoutjs 的 applybindings 需要几毫秒,然后将 observable 数组设置为 Select 控件的选项。我需要挂钩到该更改事件,以便我可以根据新的选项集做一些事情。
在有人说为什么不处理可观察数组的更改之前,我无法在我拥有事件处理程序的位置访问该可观察数组。
更新 2:
这里有更多信息。
我有一个选择控件,它有一个自定义绑定,就像这样。
@Html.KnockOutDropDownListFor(rule => ruleTemplate.RuleReserveWordId, new List<SelectListItem>(), null,
new {data_bind = "options: $root.RuleReserveWords, optionsText:'Name', optionsValue:'RuleReserveWordId', typeaheadCombobox: {sizeClass : 'input-mini'}" }
@Html.KnockoutDropDownlIstFor 是我编写的一个自定义 ASP.NET MVC 帮助程序,用于创建一个具有所有适当剔除相关属性的选择控件。它最终将一个选择控件呈现给 DOM。
我想要的选择控件应该是一个自动完成/预先输入的组合框。由于我们使用的是引导程序,因此我们使用了来自此处的引导程序插件
https://github.com/danielfarrell/bootstrap-combobox
在我的自定义绑定中,我尝试调用插件。
selectControl.customcombobox();
该插件基本上在选择控件上创建了一个输入控件并隐藏了选择控件。同时,它尝试访问选择控件的选项,并在用户开始键入时设置为输入控件的下拉菜单。
问题是由于我很早就调用了ko.applybindings(因为我认为无论我在哪里调用applybindings,一旦绑定都设置好,UI会自动更新),到调用插件时,绑定还没有边界。因此,选择控件没有设置实际的选项。因此,输入控件没有设置任何值。
如果我在几毫秒后调用插件,它会在绑定完成时工作。但这是有风险的,因为如果服务器调用时间更长,事情就会再次中断。
这就是为什么我想看看是否有办法找到
1)当使用jquery更新选择控件选项时(从没有选项到绑定后的某些选项)。没有办法直接做到这一点。有些人建议使用更新的 DOM,但它不适用于所有浏览器并且已被弃用。
或者
2) 在敲除中找到一种方法来找出绑定到选择控件的实际 observablearray 何时更新(在此示例中为 RuleReserveWords)。这将是我的首选方式。
我不能使用“更新”,因为每次更改选择控件中选择的值时都会调用它。这不是我想要的。
只要我知道何时更新选项,我就有办法更新选项。
我尝试的另一种方法是这样。在调用插件之前,我尝试添加选项以自己选择控制。DOM 渲染得很好,但不知何故,在绑定后没有立即设置选择。
ko.bindingHandlers.typeaheadCombobox = {
init: function (element, valueAccessor, allBindingsAccessor)
{
var valueUnwrapped = ko.utils.unwrapObservable(valueAccessor());
var selectControl = $(element);
var options = allBindingsAccessor().options;
var optionsValuePropertyName = allBindingsAccessor().optionsValue;
var optionsTextPropertyName = allBindingsAccessor().optionsText;
//Add appropriate class for the typeahead combobox plugin to work
selectControl.addClass('combobox');
$.each(options(), function (index, option)
{
var value = null;
var text = null;
for (var propertyName in option)
{
if (propertyName)
{
if (propertyName == optionsValuePropertyName)
{
value = option[propertyName];
}
else if (propertyName == optionsTextPropertyName)
{
text = option[propertyName];
}
}
}
if (value && text)
{
selectControl.append('<option value=' + value() + '>' + text() + '</option>');
}
});
//Call bootstrap custom combobox plugin on the select control
selectControl.customcombobox(options());
//Find the input control that is created by the bootstrap custom combobox plugin to set input control settings like size, style, validation attributes, etc
var inputControl = selectControl.parent().find('input');
inputControl.attr('name', selectControl.attr('name'));
inputControl.attr('data-val', selectControl.attr('data-val'));
inputControl.attr('data-val-required', selectControl.attr('data-val-required'));
inputControl.attr('style', selectControl.attr('style'));
if (inputControl && valueUnwrapped && valueUnwrapped.sizeClass) //Used the sizeClass instead of class itself becasue IE7 was having issues if using class or 'class' for custom bindings.
{
inputControl.addClass(valueUnwrapped.sizeClass);
}
}