我有一个可以访问Select控件(Combobox)的场景,我需要一种在源/选项列表发生变化时触发事件的方法。
例如,如果我有一个select控件,它首先选择Option1和Option2作为选项, 当选项更改为Option1,Option3,Option4时,我需要一种方法来触发事件。我不在乎是否添加了新选项,删除了新选项,或者是否新添加了所有项目。当select选项的选项发生变化时,我想要的只是一个事件处理程序。
其中一位朋友建议更改DOM,因为选项元素已添加到DOM中,但我不确定,因为每次更改页面中的任何dom元素时,DOM更改都会被触发。
更新: 对此感到抱歉。我不是在寻找选择改变。我正在寻找实际的选项列表的变化。
我正在使用Knockoutjs并且我将一个可观察数组绑定到选择控件作为选项。 knockoutjs的applybindings需要几毫秒,然后将可观察数组设置为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的选择控件。
我想要的选择控件应该是autocomplete / typeahead comobox。由于我们使用的是bootstrap,因此我们使用了一个bootstrap插件
https://github.com/danielfarrell/bootstrap-combobox
在我的自定义绑定中,我试图调用该插件。
selectControl.customcombobox();
该插件基本上创建了对select控件的输入控件,并隐藏了select控件。 同时,当用户开始输入时,它会尝试访问选择控件的选项并设置为输入控件的下拉菜单。
问题是因为我非常早地调用ko.applybindings(因为我认为无论我在哪里调用applybindings,一旦绑定全部设置,UI将自动更新),在调用插件时,绑定尚未受约束。所以,选择控件 没有实际的选项集。因此,输入控件没有设置任何值。
如果我在几毫秒之后调用插件,它就可以在那时完成绑定。但它的风险是因为如果服务器调用时间更长,事情就会再次破裂。
这就是为什么我想看看是否有办法找到
1)使用jquery更新选择控件选项(从无选项到绑定后的某些选项)。没有办法直接这样做。 有些人建议使用DOM更新但它并不适用于所有浏览器并且被删除。
或
2)在knockout中找到一种方法,以找出更新绑定到select控件的实际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);
}
}
答案 0 :(得分:0)
我假设RuleReserveWords是一个淘汰可观察数组?在这种情况下,您可以订阅它。订阅应该在列表更改时触发...
viewModel.RuleReserveWords.subscribe(function() { ... list has changed here... })