bootstrap-multiselect中的Knockout自定义绑定未应用

时间:2016-10-05 17:00:59

标签: javascript knockout.js

我正在将Bootstrap Multiselect组件与knockout和requirejs结合使用。 multiselect组件包含一个自定义绑定来处理敲除绑定,但它似乎并不适用于所有情况。但是,如果我将其绑定直接复制并粘贴到我的viewmodel中,它可以正常工作。

例如,我有以下模板:

<select multiple="multiple" class="form-control bootstrap-multiselect" style="display:none;"
        data-bind="options:rolesList,
                    selectedOptions:selectedRoles,
                    optionsText:'name',
                    optionsValue:'id',
                    multiselect:true"></select>

我的requirejs设置如下:

require(['knockout', 'bootstrap-multiselect'], function (ko, multiselect) {
    var RoleData = function(items) {
        this.rolesList = ko.observableArray(items);
        this.selectedRoles = ko.observableArray();
    }
    var viewModel = new RoleData(data);

    ko.applyBindings(viewModel);
}

这是他们的绑定:

if (typeof ko !== 'undefined' && ko.bindingHandlers && !ko.bindingHandlers.multiselect) {
    ko.bindingHandlers.multiselect = {
        after: ['options', 'value', 'selectedOptions', 'enable', 'disable'],

        init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
            var $element = $(element);
            var config = ko.toJS(valueAccessor());

            $element.multiselect(config);

            if (allBindings.has('options')) {
                var options = allBindings.get('options');
                if (ko.isObservable(options)) {
                    ko.computed({
                        read: function () {
                            options();
                            setTimeout(function () {
                                var ms = $element.data('multiselect');
                                if (ms)
                                    ms.updateOriginalOptions();//Not sure how beneficial this is.
                                $element.multiselect('rebuild');
                            }, 1);
                        },
                        disposeWhenNodeIsRemoved: element
                    });
                }
            }

            //value and selectedOptions are two-way, so these will be triggered even by our own actions.
            //It needs some way to tell if they are triggered because of us or because of outside change.
            //It doesn't loop but it's a waste of processing.
            if (allBindings.has('value')) {
                var value = allBindings.get('value');
                if (ko.isObservable(value)) {
                    ko.computed({
                        read: function () {
                            value();
                            setTimeout(function () {
                                $element.multiselect('refresh');
                            }, 1);
                        },
                        disposeWhenNodeIsRemoved: element
                    }).extend({ rateLimit: 100, notifyWhenChangesStop: true });
                }
            }

            //Switched from arrayChange subscription to general subscription using 'refresh'.
            //Not sure performance is any better using 'select' and 'deselect'.
            if (allBindings.has('selectedOptions')) {
                var selectedOptions = allBindings.get('selectedOptions');
                if (ko.isObservable(selectedOptions)) {
                    ko.computed({
                        read: function () {
                            selectedOptions();
                            setTimeout(function () {
                                $element.multiselect('refresh');
                            }, 1);
                        },
                        disposeWhenNodeIsRemoved: element
                    }).extend({ rateLimit: 100, notifyWhenChangesStop: true });
                }
            }

            var setEnabled = function (enable) {
                setTimeout(function () {
                    if (enable)
                        $element.multiselect('enable');
                    else
                        $element.multiselect('disable');
                });
            };

            if (allBindings.has('enable')) {
                var enable = allBindings.get('enable');
                if (ko.isObservable(enable)) {
                    ko.computed({
                        read: function () {
                            setEnabled(enable());
                        },
                        disposeWhenNodeIsRemoved: element
                    }).extend({ rateLimit: 100, notifyWhenChangesStop: true });
                } else {
                    setEnabled(enable);
                }
            }

            if (allBindings.has('disable')) {
                var disable = allBindings.get('disable');
                if (ko.isObservable(disable)) {
                    ko.computed({
                        read: function () {
                            setEnabled(!disable());
                        },
                        disposeWhenNodeIsRemoved: element
                    }).extend({ rateLimit: 100, notifyWhenChangesStop: true });
                } else {
                    setEnabled(!disable);
                }
            }

            ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
                $element.multiselect('destroy');
            });
        },

        update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
            var $element = $(element);
            var config = ko.toJS(valueAccessor());

            $element.multiselect('setOptions', config);
            $element.multiselect('rebuild');
        }
    };
}

如果我在他们的代码中放置断点,则敲除(ko)未定义。我该如何解决这个问题?

0 个答案:

没有答案