2016-03-23 35 views
11

Sto cercando di integrare Select2 nell'app Angular2 che sto costruendo. Sono riuscito a ottenere select2 in esecuzione e le mie selezioni multiple vengono trasformate come previsto. Il mio problema ora è come dovrei ottenere i valori selezionati e quale evento dovrei usare per l'associazione. Ho provato a collegare l'evento (change) all'elemento select ma non è successo nulla. Forse dovrei usare qualche altro evento sul creato dall'elemento plugin select2-container?
Il plug-in select2 è integrato dopo la risposta this.
Qualcuno ha provato un mix simile? È possibile farlo funzionare o devo invece passare alla direttiva ng2-select?Integrare Select2 nell'app Angular2

Aggiornamento domanda
Bonus :) - Anche se mi arrendo select2 e uso standard selezione multipla, come devo ottenere il suo valore? Ho provato a legarlo a una proprietà con [(ngModel)]="_selectedValues" ma rimane vuoto quando seleziono qualsiasi opzione. La casella di controllo multipla è l'unico modo per una scelta multipla?

Update 2
Per la domanda di bonus - la soluzione che ho trovato è stato quello di utilizzare un evento modo vincolante come (change)="selectedValues=$event.target.selectedOptions". Poi ho aggiunto un setter per la proprietà selectedValues in questo modo:

public set selectedValues(value: Array<any>) { 
    this._selectedValues.length = 0; 
    for(let v of value){ 
     this._selectedValues.push(v.value); 
    } 
}; 
+0

Per quanto riguarda NG2-select, ho fonte di avere troppo immaturo finora per poter utile per qualcosa di diverso da casi d'uso veramente di base. –

risposta

27

L'unica soluzione a lavorare per la select2 ho trovato, è sempre il valore con jQuery nel metodo ngAfterViewInit in questo modo:

jQuery('.fields-select').on(
     'change', 
     (e) => this._selectedValues = jQuery(e.target).val() 
); 

Quindi il mio codice finale è simile al seguente:

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() 
     ); 
    }; 
} 

An d nel modello:

<select id="fields" class="form-control fields-select" multiple="multiple"> 
    <option *ngFor="#field of _availableFields" [value]="field">{{field}}</option> 
</select> 

Spero che questo salverà la vita di qualcuno, un giorno :)

+0

come importate select2 e jquery allo stesso tempo? Ho problemi con esso – Jonathan

+1

@ Jonathan Ho appena aggiunto loro nel punto di ingresso della mia app - nel mio caso l'index.html, come questo: ' ' –

+1

@RadoslavStoyanov Grazie per la risposta. Qualche idea su come rendere jQuery selezionare 2 compatibile con Angular http e osservabile? – Shahin

2

Ho fatto la mia propria implementazione di esso, con le opzioni, il valore, e gli elementi disponibili come ingresso params della mia componente. Questa è la mia prima versione di esso, potrebbe essere molto flessibile e aumentata abbastanza facilmente.

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); 
    } 
} 

E si può chiamare così

<custom-select [items]="array" [options]="{multiple:true}" (valueChange)="update($event)" [value]="valueVar"></custom-select>