web-dev-qa-db-ja.com

Select2をAngular2アプリに統合する

作成している_Select2_アプリに_Angular2_を統合しようとしています。私はなんとか_select2_を実行し、複数の選択が期待どおりに変換されます。ここでの問題は、選択した値をどのように取得するか、およびバインディングにどのイベントを使用するかです。 select要素に_(change)_イベントをバインドしようとしましたが、何も起こりませんでした。たぶん、プラグイン_select2-container_要素によって作成された他のイベントを使用する必要がありますか?
_select2_プラグインは this の回答に従って統合されています。
誰かが同様のミックスを試しましたか?それを機能させることは可能ですか、代わりに 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);
    }
};
_
11

私が見つけたselect2の唯一の有効なソリューションは、次のようにngAfterViewInitメソッドでjQueryを使用して値を取得することです。

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>

これがいつか誰かの命を救うことを願っています:)

30

オプション、値、および使用可能な項目をコンポーネントの入力パラメーターとして使用して、独自に実装しました。これは私の最初のバージョンです。非常に柔軟で、非常に簡単に拡張できます。

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>
3
S.Galarneau