淘汰具有延迟加载的多选下拉列表
Knockout multiselect dropdown with lazy loading
我在处理这个处理程序时遇到了困难,我部分是从这里得到的,部分是被破解的。我仍然在了解处理人员,所以我认为我的问题是由于缺乏理解。
我在一个显示在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);
}
}
所以我的问题是,我以为我有数组值,但我最终得到了可观察的值。这导致我的数组长度检查总是通过,所以它不断添加初始值。
我不得不更改初始行
var ddOptions = unwrap(valueAccessor);
至
var ddOptions = unwrap(valueAccessor()); // added () :/
尝试创建带有项的临时数组,并直接更新valueAccessor observable数组:
var items = [];
for (var i = 0; i < selectedOptions.length; i++) {
items.push({ Value: selectedOptions[i], Text: '' });
}
// items
valueAccessor(items);
相关文章:
- 如何根据对具有多行的先前列表的选择来动态加载下拉列表
- 如何在页面加载后禁用下拉列表框项目的选择
- 如果使用jquery在页面加载时未选择任何选项,如何禁用下拉列表
- 在Moqui中,如何在html.ftl中加载数据库表数据作为下拉列表
- 淘汰具有延迟加载的多选下拉列表
- 在下拉列表中加载默认值并调用 onchange 事件
- 根据下拉列表值加载 html 表单
- Jquery - 根据下拉菜单选择加载 XML 文件
- 下拉菜单 TBS - 加载值
- Jquery 依赖下拉列表以加载到文档就绪
- 如何从下拉菜单Angular加载模板
- 下拉式javascript加载
- 默认情况下,浏览器延迟加载悬停图像
- 根据php中的下拉列表重新加载页面
- 从下拉菜单中加载数据到文本机器人
- setTimeout用于在下拉列表中加载项
- Jquery选择框(下拉框),加载第一个值
- 我如何在不重写整个应用程序(Laravel + jQuery, SPA风格)的情况下块结果(延迟加载?)
- 级联下拉更改页面加载
- 使用js下拉菜单预加载图像