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