我正在尝试使用bootstrap-multiselect与Aurelia合作。让它工作或多或少,但不确定它是最好的解决方案,还是我可能遇到麻烦。
Bootstrap-multiselect是一个jquery插件,可以将普通选择(多个)转换为带有复选框的下拉列表(http://davidstutz.github.io/bootstrap-multiselect/)
我的第一个问题是让它使用动态创建的选项。当我的选项数组(作为可绑定属性创建)发生更改时,我通过使用插件“rebuild”功能解决了这个问题。然而原始选择的选项还没有创建,所以我使用setTimeout来延迟重建,所以Aurelia重建了选择。感觉就像一个“肮脏”的解决方案,我对Aurelia的生活方式知之甚少,以确保它始终有效。
第二个问题是组件的值不会更新,但更改方法将触发。我通过触发更改事件解决了这个问题(找到了一些其他插件的例子)。工作正常,价值将被更新,但更改方法将触发两次。这不是一个大问题,但如果更改会耗费一些时间(例如从数据库中获取数据等),则可能会出现问题。
有关改进代码的建议吗?
<template>
<select value.bind="value" multiple="multiple">
<option repeat.for="option of options"Value.bind="option.value">${option.label}</option>
</select>
</template>
import {customElement, bindable, inject} from 'aurelia-framework';
import 'jquery';
import 'bootstrap';
import 'davidstutz/bootstrap-multiselect';
@inject(Element)
export class MultiSelect {
@bindable value: any;
@bindable options: {};
@bindable config: {};
constructor(private element) {
this.element = element;
}
optionsChanged(newVal: any, oldVal: any) {
setTimeout(this.rebuild, 0);
}
attached() {
var selElement = $(this.element).find('select');
selElement.multiselect(
{
includeSelectAllOption: true,
selectAllText: "(All)",
selectAllNumber: false,
numberDisplayed: 1,
buttonWidth: "100%"
})
.on('change', (event) => {
if (event.originalEvent) { return; }
var notice = new Event('change', { bubbles: true });
selElement[0].dispatchEvent(notice);
});
}
detached() {
$(this.element).find('select').multiselect('destroy');
}
rebuild = () => {
$(this.element).find('select').multiselect('rebuild');
}
}
答案 0 :(得分:1)
通过将$(this.element).find('select').multiselect('rebuild');
推送到optionsChanged()
处理程序内的microTaskQueue,可以解决第一个问题。通过这种方式,Aurelia将在渲染新选项后触发此事件。
你的第二个问题实际上并不是问题。发生的事情是@bindable
属性默认是单向的。您应该将value
属性声明为双向。然后,您应该更新value
事件中的multiselect.change
。
最后,您的自定义元素应该是这样的:
import {inject, bindable, bindingMode, TaskQueue} from 'aurelia-framework';
@inject(TaskQueue)
export class MultiselectCustomElement {
@bindable options;
@bindable({ defaultBindingMode: bindingMode.twoWay }) value = [];
constructor(taskQueue) {
this.taskQueue = taskQueue;
}
attached() {
$(this.select).multiselect({
onChange: (option, checked) => {
if (checked) {
this.value.push(option[0].value);
} else {
let index = this.value.indexOf(option[0].value);
this.value.splice(index, 1);
}
}
});
}
optionsChanged(newValue, oldValue) {
if (oldValue) {
this.taskQueue.queueTask(() => {
this.value = [];
$(this.select).multiselect('rebuild');
});
}
}
}
正在运行示例:https://gist.run/?id=60d7435dc1aa66809e4dce68329f4dab
希望这有帮助!