0

我对这个处理程序有困难,我部分地从这里得到,部分地被黑客攻击在一起。我仍然对处理程序有所了解,所以我假设我的问题源于缺乏理解。

我在一个模板中使用这个处理程序,该模板显示在一个 ko“if”语句中。当模板被包含/排除时,打开和关闭选项会重复。这是因为unwrap(valueAccessor()).push(item)线。我尝试过独立构建数组,然后直接将 valueAccessors 值设置为数组,但 ui 没有响应,它只能通过推送项目来工作。

我怎样才能解决这个问题?我是正确地进行绑定还是有更好更合适的方法?我已经用注释标记了代码行,以指示我的问题发生在哪里。

multiSelectCheck: {
        init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
            // This will be called when the binding is first applied to an element
            // Set up any initial state, event handlers, etc. here
            var bindings = allBindingsAccessor();
            var ddOptions = unwrap(valueAccessor);
            var selectedOptions = unwrap(bindings.selectedOptions);
            var options = unwrap(bindings.multiselectOptions) || [];
            var optionsCaption = unwrap(bindings.optionsCaption);
            var displaySelected = unwrap(bindings.selectedList) || 5;
            var loadingCaption = unwrap(bindings.loadingCaption);
            var delimiter = unwrap(bindings.splitSelectedBy) || ',';
            var setInitial = unwrap(bindings.setInitialValue);

            // display loader in dropdown
            ko.computed(function () {
                if (unwrap(bindings.loading)) {
                    var spinnerClass = 'fa fa-spinner fa-spin fa-lg';
                    var spinner = loadingCaption || '<span><i class="' + spinnerClass + '"></i> Loading...</span>';

                    // set text to loading
                    $(element).multiselect({ selectedList: 0, noneSelectedText: spinner, selectedText: spinner }).multiselect('disable');
                    $(element).multiselect('refresh');
                }
            }, null, { disposeWhenNodeIsRemoved: element });

            // internal options
            var internal = { selectedList: displaySelected, noneSelectedText: 'Select options', selectedText: '# selected' }

            // merge options with provided options
            options = $.extend(internal, options);

            // pass the original optionsCaption to the similar widget option
            if (optionsCaption) {
                options.noneSelectedText = unwrap(optionsCaption);
            }

            // remove this and use the widget's
            bindings.optionsCaption = '';

            // populate intitial values if available
            if (ddOptions && !ddOptions.length && setInitial) {

                if (selectedOptions) {

                    // create array from value
                    if (typeof selectedOptions == 'string') {
                        selectedOptions = selectedOptions.split(delimiter);
                        selectedOptions = selectedOptions.filter(function (e) { return !!e; }); // filter empty nodes
                        bindings.selectedOptions(selectedOptions);
                    }

                    // add options objects to array of available options
                    for (var i = 0; i < selectedOptions.length; i++) {
                        var item = { Value: selectedOptions[i], Text: '' };
                        //console.log(item);

                        //#### THIS IS THE LINE OF CODE IN QUESTION ####
                        unwrap(valueAccessor()).push(item);
                    }
                }
            }

            // apply multiselect plugin
            var elm = $(element).multiselect(options).multiselectfilter({ filterOnly: true, autoReset: true });

            // refresh the plugin
            $(element).multiselect('refresh');

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

        },
        update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
            // This will be called once when the binding is first applied to an element,
            // and again whenever the associated observable changes value.
            // Update the DOM element based on the supplied values here.
            var bindings = allBindingsAccessor();
            var selectOptions = unwrap(bindings.multiSelectCheck);
            var selectedOptions = unwrap(bindings.selectedOptions);
            var delimiter = unwrap(bindings.splitSelectedBy) || ',';
            var displaySelected = unwrap(bindings.selectedList) || 5;

            // remove this and use the widget's 
            bindings.optionsCaption = '';

            // handle delimited values
            if (typeof selectedOptions == 'string') {
                selectedOptions = selectedOptions.split(delimiter);
                selectedOptions = selectedOptions.filter(function (e) { return !!e; }); // filter empty nodes
                bindings.selectedOptions(selectedOptions);
            }

            ko.bindingHandlers.options.update(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
            var data = unwrap(valueAccessor());
            var showFilter = (data && data.length > 10) ? 'enable' : 'disable';

            setTimeout(function () {
                var $element = $(element);
                $element.multiselect({ selectedList: displaySelected, noneSelectedText: 'Select options', selectedText: '# selected' }).multiselect('enable').multiselect('refresh').multiselectfilter('refresh');
                $element.multiselectfilter(showFilter);
                $element.multiselect('refresh');
            }, 0);
        }
    }
4

2 回答 2

0

所以我的问题最终是我认为我有数组值,但我最终得到了 observable 。这导致我的数组长度检查始终通过,因此它不断添加初始值。

我不得不改变初始化行

var ddOptions = unwrap(valueAccessor);

var ddOptions = unwrap(valueAccessor()); // added () :/
于 2015-03-04T02:59:05.163 回答
0

尝试使用项目创建临时数组并直接更新 valueAccessor 可观察数组:

var items = [];
for (var i = 0; i < selectedOptions.length; i++) {
   items.push({ Value: selectedOptions[i], Text: '' });
}

// items
valueAccessor(items);
于 2015-03-03T06:54:22.270 回答