当select控件的源/选项发生变化时,JQuery会触发一个事件

时间:2013-01-22 22:14:00

标签: jquery select binding event-handling knockout.js

我有一个可以访问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);
        }        
    }

1 个答案:

答案 0 :(得分:0)

我假设RuleReserveWords是一个淘汰可观察数组?在这种情况下,您可以订阅它。订阅应该在列表更改时触发...

viewModel.RuleReserveWords.subscribe(function() { ... list has changed here... })