Aurelia trying to load HTML from Select2?

青春壹個敷衍的年華 提交于 2019-11-29 15:07:27

The purpose of <require from="...."></require> is to import a view resource into your view. View resources are things like custom elements or custom attributes. When you add <require from="select2/js/select2.min.js"></require> to your template aurelia loads the module and thinks it's the view-model for a custom element. It then attempts to load the view for it which is why you see the attempt to load .../select2.min.html

The "aurelia way" to integrate select2 would be to create a custom attribute that applies select2 to the element. Something like this:

select2-custom-attribute.js

import {customAttribute, inject} from 'aurelia-framework';
import {DOM} from 'aurelia-pal';
import $ from 'jquery';
import 'select2'; // install the select2 jquery plugin
import 'select2/css/select2.min.css!' // ensure the select2 stylesheet has been loaded

@customAttribute('select2')
@inject(Element)
export class Select2CustomAttribute {
  constructor(element) {
    this.element = element;
  }

  attached() {
    $(this.element)
     .select2(this.value);
     //.on('change', () => this.element.dispatchEvent(DOM.createCustomEvent('change')));
  }

  detached() {
    $(this.element).select2('destroy');
  }
}

Then you'd import the custom attribute into your view and use it like this:

app.html

  <require from="select2-custom-attribute"></require>

  <select select2 value.bind="selectedState">
    <option repeat.for="state of states" model.bind="state">${state.name}</option>
  </select>

Or like this if you need to pass some options to select2 (this assumes your view-model has a property named "options" containing the select2 options as described in their docs):

app.html

  <require from="select2-custom-attribute"></require>

  <select select2.bind="options" value.bind="selectedState">
    <option repeat.for="state of states" model.bind="state">${state.name}</option>
  </select>

Here's a working example: https://gist.run/?id=0137059e029fc4b3ccd367e385f47b19

Unfortunately I was unable to import select2 properly using jspm, even when using the shim listed here. If you hit the same issue, you'll have to remove the import statements related to select2 from the custom attribute code above and load the select2 js and css with script/link tags in your document.

For the sake of completion, firing the change event in Jeremy's solution results in a recursive loop and causes exception to fix it I had to do:

attached() {
    $(this.element)
     .select2(this.value)
     .on('change', evt => {
         if (evt.originalEvent) { return; }
         this.element.dispatchEvent(new Event('change'));
     });
}

I could then do:

<require from="select2-custom-attribute"></require>

<select select2.bind="options" value.bind="selectedState" change.delegate="changeCallback($event)">
    <option repeat.for="state of states" model.bind="state">${state.name}</option>
</select>

changeCallback($event) can be a function on your vm e.g.

changeCallback(evt: Event): void {
    console.log(evt);
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!