Интегрируйте Select2 в приложение Angular2
Я пытаюсь интегрировать Select2
в приложение Angular2
, которое я создаю. Мне удалось запустить Select2
, и мои множественные выборки преобразуются, как ожидалось. Теперь моя проблема заключается в том, как я должен получать выбранные значения и какое событие использовать для привязки. Я попытался привязать событие (change)
к элементу select, но ничего не произошло. Может быть, мне нужно использовать какое-то другое событие для созданного элементом плагина select2-container
?
Плагин Select2
интегрирован в следующий этот ответ.
Кто-нибудь пробовал аналогичную смесь? Можно ли заставить его работать, или я должен вместо этого перейти на ng2-select?
Обновить
Бонусный вопрос:) - Даже если я откажусь от Select2
и использую стандартный множественный выбор, как мне его получить? Я попытался привязать его к свойству с помощью [(ngModel)]="_selectedValues"
, но он остается пустым, когда я выбираю любую опцию. Является ли множественный флажок единственным способом для множественного выбора?
Обновление 2
Для вопроса о бонусе - обходной путь, который я нашел, - использовать одностороннее связывание событий, например (change)="selectedValues=$event.target.selectedOptions"
. Затем я добавил свойство setter
для свойства selectedValues
следующим образом:
public set selectedValues(value: Array<any>) {
this._selectedValues.length = 0;
for(let v of value){
this._selectedValues.push(v.value);
}
};
Ответы
Ответ 1
Единственное работающее решение для select2
, которое я нашел, получает значение с помощью jQuery в методе ngAfterViewInit
следующим образом:
jQuery('.fields-select').on(
'change',
(e) => this._selectedValues = jQuery(e.target).val()
);
Итак, мой последний код выглядит так:
import {Component, AfterViewInit} from 'angular2/core';
@Component({
selector: 'filters',
templateUrl: 'template.html'
})
export class FiltersComponent implements AfterViewInit {
private _availableFields: Array<any> = ['Value1', 'Value2', 'Value3','Value4'];
private _selectedFields: Array<string> = [];
ngAfterViewInit(){
jQuery('.fields-select').select2();
jQuery('.fields-select').on(
'change',
(e) => this._selectedFields = jQuery(e.target).val()
);
};
}
И в шаблоне:
<select id="fields" class="form-control fields-select" multiple="multiple">
<option *ngFor="#field of _availableFields" [value]="field">{{field}}</option>
</select>
Надеюсь, что когда-нибудь это спасет кого-то:)
Ответ 2
Я сделал свою собственную реализацию, с параметрами, значением и доступными элементами в качестве входных параметров моего компонента. Это моя первая версия, она может быть очень гибкой и легко дополняется.
import { Component, ElementRef, Input, Output, AfterViewInit, EventEmitter, ViewChild } from '@angular/core';
declare var $: any;
@Component({
selector: 'custom-select',
template: `<select #select class="form-control"></select>`
})
export class CustomSelectComponent implements AfterViewInit {
@ViewChild('select') private select: ElementRef;
@Input() items: any[];
@Input() options: any = {};
@Input() value: any;
@Output() valueChange = new EventEmitter<string[]>();
constructor() { }
ngAfterViewInit() {
let selectElement = $(this.select.nativeElement);
if (this.isMultiple()) {
selectElement.attr('multiple', true);
}
selectElement.select2({
data: $.map(this.items, (obj: any) => {
let item = {
id: this.options.identifier ? obj[this.options.identifier] : obj.id,
text: this.options.name ? obj[this.options.name] : obj.name
};
if ($.trim(item.id) === '') { console.warn(`No 'id' value has been set for :`, obj); }
if ($.trim(item.text) === '') { console.warn(`No 'name' value has been set for :`, obj); }
return item;
})
});
$(selectElement).val(this.value).trigger('change');
selectElement.on('change', (e: any) => {
this.valueChange.emit($(e.target).val());
});
};
private isMultiple() {
return !!(this.options && this.options.multiple === true);
}
}
И вы можете так называть
<custom-select [items]="array" [options]="{multiple:true}" (valueChange)="update($event)" [value]="valueVar"></custom-select>