web-dev-qa-db-fra.com

Des exemples d'intégration de Select2 avec Angular2 Components?

J'ai essayé de trouver une démonstration/exemple de la façon d'intégrer Select2 dans un composant angulaire 2.

Mon objectif final est d’utiliser 2 options ajax pour alimenter la liste déroulante au fur et à mesure que je commence à taper dans la zone de sélection aka https://select2.github.io/examples.html#data-ajax

Jusqu'à présent, mes pouvoirs sur Google ninja m'ont échoué :(

Exemples d'échec d'intégration avec select2 ... y a-t-il d'autres suggestions?

9
andycwk

Lorsque j’ai commencé à chercher des exemples de listes déroulantes multi-sélections dans Select2 dans Angular2, je n’étais pas en mesure de trouver celui que je cherchais. J'ai réalisé que parfois le pouvoir de Google ninja ne fonctionnait pas. Je devais l'écrire moi-même. Cependant, j'ai pensé le partager et ne pas laisser le ninja de Google se rallumer pour cela. :)

Cliquez ici pour voir la démo de travail

Le cœur de ceci est d’envelopper le select2 dans un composant angulaire.

export class DummySelect {
  constructor(private id: string){
    $(id).select2({
      width: '100%',
      ajax: {
        url: 'https://api.github.com/search/repositories',
        datatype: 'json',
        delay: 250,
        data: function(params: any){
          return {
            q: params.term
          };
        },
        processResults: function(data:any, params: any){
          return {
            results:
              data.items.map(function(item) {
                return {
                  id: item.id,
                  text: item.full_name
                };
              }
            )};
          },
        cache: true  
      },
      placeHolder: 'Search...',
      minimumInputLength: 2 
    })
  }

  getSelectedValues(private id: string){
    return $(id).val();
  }
}
3
Shahid

Voyons comment je suis arrivé à travailler avec le select2. Mon but était d'init le select2 et d'ajouter l'attribut _ngcontent- pour permettre de les styler via scss dans ma portée. 

Html:

<select multiple="multiple" style="display: none;">
    <option *ngFor="#item of people" [value]="item.id">
        {{item.name}}
    </option>
</select>

Init dans TypeScript sur ngAfterViewInit:

ngAfterViewInit()
{
    var element = (<any>$('select')).select2().siblings('.select2-container')[0];
    var attribute = ObjectHelper.setElementContentAttribute(this.m_elementRef.nativeElement, element, true);
}

Et les fonctions magiques spéciales permettant de cloner l'attribut _ngcontent aux enfants. Très utile pour de nombreuses bibliothèques tierces, où du contenu dynamique est généré:

public static getAngularElementTag(element: Element): string
{
    var attrs = [].filter.call(element.attributes, at => /^_nghost-/.test(at.name));
    if (attrs.length == 0)
    {
        return null;
    }
    return attrs[0].name.replace("_nghost-", "_ngcontent-");
}


public static setElementContentAttribute(hostElement: Element, targetElement: Element, setRecursive?: boolean): string
{
    var attribute = this.getAngularElementTag(hostElement);
    setRecursive = (setRecursive !== undefined) ? setRecursive : false;
    if (attribute !== null)
    {
        this._setElementContentAttribute(targetElement, setRecursive, attribute);
        return attribute;
    }
    else
    {
        return null;
    }
}

private static _setElementContentAttribute(targetElement: Element, recursive: boolean, attribute) {
    targetElement.setAttribute(attribute, '');
    if (recursive) {
        for (var i = 0; i < targetElement.childElementCount; i++) {
            this._setElementContentAttribute(<Element>targetElement.childNodes[i], recursive, attribute);
        }
    }
}

C'est fait juste pour dénommer l'élément d'entrée. Pour les éléments ajoutés dynamiquement (sélections, sélecteur), vous devrez probablement capturer certains événements et refaire la magie.

0
prespic