【问题标题】:boostrap-multiselect plugin in AureliaAurelia 中的引导多选插件
【发布时间】:2017-06-07 03:41:07
【问题描述】:

我正在尝试让 bootstrap-multiselect 与 Aurelia 一起使用。让它或多或少地工作,但不确定它是否是最好的解决方案,或者我是否会遇到麻烦。

Bootstrap-multiselect 是一个 jquery 插件,可以将普通的选择(多选)变成带有复选框的下拉菜单 (http://davidstutz.github.io/bootstrap-multiselect/)

我的第一个问题是让它与动态创建的选项一起工作。当我的选项数组(创建为可绑定属性)发生更改时,我通过使用插件“重建”功能解决了这个问题。然而,原始选择 hhas 的选项尚未创建,因此我使用 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');
    }
}

【问题讨论】:

  • 我在使用 DataTables 时遇到了一些相同类型的问题,最后我自己写了。 Aurelia 的绑定很棒,但我还没有学会在 DOM 更新完成时触发事件的方法。这就是您要关注的地方——如何在正确的时刻运行组件的rebuild 方法。

标签: aurelia bootstrap-multiselect


【解决方案1】:

您的第一个问题可以通过将$(this.element).find('select').multiselect('rebuild'); 推送到optionsChanged() 处理程序内的微任务队列中来解决。这样,Aurelia 将在渲染新选​​项后触发此事件。

您的第二个问题实际上不是问题。发生的事情是 @bindable 属性默认是单向的。您应该将value 属性声明为双向。然后,您应该更新 multiselect.change 事件中的 value

最后,你的自定义元素应该是这样的:

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

希望这会有所帮助!

【讨论】:

  • 感谢您的建议。很抱歉直到现在才回复您。当你有麻烦来帮助我时,这对我来说是非常粗鲁的。到目前为止,我一直在研究项目的其他部分,所以忘记了这一点,因为它有点工作。我认为默认情况下 bindign 是两种方式= 是否将选择上的模板中的绑定更改为 value.two-way。我会试试你的代码,它更干净。不适用于在代码中选择选定的值,但会尝试使其正常工作。
猜你喜欢
  • 2016-11-14
  • 2017-05-28
  • 1970-01-01
  • 2019-11-02
  • 1970-01-01
  • 1970-01-01
  • 2015-02-04
  • 1970-01-01
  • 2019-09-04
相关资源
最近更新 更多