Comment sélectionner un élément par nom de classe en utilisant jqLite?

110

J'essaie de supprimer jquery de mon application Angular.js afin de l'alléger, et de mettre le jqLite d'Angular à la place. Mais l'application fait un usage intensif de find ('# id') et find ('.classname'), qui ne sont pas pris en charge par jqLite, uniquement 'tag names' (selon la documentation)

Je me suis demandé quelle serait la meilleure approche pour le changer. Une approche à laquelle j'ai pensé est de créer des balises HTML personnalisées. par exemple: changer
<span class="btn btn-large" id="add-to-bag">Add to bag</span>

à

<a2b style="display:none;"><span class="btn btn-large" >Add to bag</span></a2b>

et

$element.find('#add-to-bag') 

à

$element.find('a2b')

Des pensées? d'autres idées?

Merci

Lior

Lior
la source
4
Les ID doivent être uniques, donc cela n'a aucun sens de trouver un élément qui est un enfant d'un autre élément par ID. Sélectionnez simplement l'élément par ID. Si vos identifiants ne sont pas uniques, changez votre identifiant en classe. En outre, vous pouvez utiliser DomElement.querySelector(".myclassname")pour sélectionner un élément décendant unique à l'aide d'un sélecteur css, ou tout ce qui correspond en y ajoutant Tout: DomElement.querySelectorAll(".myclassname")cela ne fonctionne bien sûr pas dans IE <9.
Kevin B
Si vous définissez un a2bélément, vous devez avoir défini une directive. Pouvez-vous faire ce qui doit être fait dans la fonction de lien de la directive, et ainsi éviter le besoin d'appeler entièrement find ()? De même avec vos classes - pouvez-vous définir des directives et mettre les fonctionnalités dont vous avez besoin dans les fonctions de liaison (ou de compilation) des directives?
Mark Rajcok
2
On dit que jqLite de @KevinB Angular ne prend en charge que les `` noms de balises ''
Lior
@MarkRajcok Je n'ai pas défini de directive. il semble fonctionner dans IE et chrome. mais même si je définirais une directive, pourquoi cela aiderait-il? J'aurais encore besoin de mettre la main sur un élément DOM.
Lior
Comment se fait-il que find ('span.btn') ou similaire ne fonctionne pas pour vous?
Fabi

Réponses:

202

Essentiellement, et comme noté par @ kevin-b:

// find('#id')
angular.element(document.querySelector('#id'))

//find('.classname'), assumes you already have the starting elem to search from
angular.element(elem.querySelector('.classname'))

Remarque: Si vous cherchez à faire cela à partir de vos contrôleurs, vous pouvez consulter la section «Utilisation correcte des contrôleurs» dans le guide des développeurs et refactoriser votre logique de présentation en directives appropriées (telles que <a2b ...>) .

psema4
la source
3
Merci! à ajouter à partir de la réponse de Ricardo Bin (liste de diffusion angular), $ document injectable pourrait également être utilisé: jsfiddle.net/ricardohbin/fTQcs
Lior
Malheureusement, l'URL référencée n'est plus valide ( docs.angularjs.org/guide/dev_guide.mvc.understanding_controller ), et il ne semble pas y avoir de remplacement dans cette section.
Per Quested Aronsson
No. angular.element (document.querySelector ('# id')) est l'alternative à: $ ('# id'), pas pour: elementArray.find ('# id')
Broda Noel
Bien - mais comme nous l'avons constaté lorsque nous construisons de nouvelles parties de notre application en angulaire, nous avons parfois besoin de «ruban adhésif» sur les anciennes parties pendant un certain temps jusqu'à ce qu'elles puissent être mises à jour ou re-factorisées. Dans notre cas, nous devions charger d'anciennes données jquery / ajax sans modifier le désordre existant, nous avons donc fait ce qui suit - $ http.get ('/ Task / GetTaskStatsByTaskId /' + taskId) .success (function (data) {angular.element (document.querySelector ('# userTasksContainer')). html (données);});
Kenn
42
Si elem est un objet jqlite, ce seraitangular.element(elem[0].querySelector('.classname'));
cleversprocket
2

angualr utilise la version allégée de jquery appelée jqlite, ce qui signifie qu'elle n'a pas toutes les fonctionnalités de jQuery. voici une référence dans la documentation angularjs sur ce que vous pouvez utiliser de jquery. Documents sur les éléments angulaires

Dans votre cas, vous devez trouver un div avec un identifiant ou un nom de classe. pour le nom de la classe, vous pouvez utiliser

var elems =$element.find('div') //returns all the div's in the $elements
    angular.forEach(elems,function(v,k)){
    if(angular.element(v).hasClass('class-name')){
     console.log(angular.element(v));
}}

ou vous pouvez utiliser un moyen beaucoup plus simple par le sélecteur de requête

angular.element(document.querySelector('#id'))

angular.element(elem.querySelector('.classname'))

ce n'est pas aussi flexible que jQuery mais quoi

Hannah Rehman
la source
1

Si cela elem.find()ne fonctionne pas pour vous, vérifiez que vous incluez le script JQuery avant le script angulaire ....

ancajic
la source
3
Bien que l'OP ait spécifiquement posé des questions sur jqLite, pour ceux qui utilisent jQuery et s'attendent à ce que find () fonctionne également avec des classes et des ID, cette réponse peut certainement aider.
Matt B
2
Pour clarifier: "Si jQuery est disponible, angular.element est un alias pour la fonction jQuery. Si jQuery n'est pas disponible, angular.element délègue au sous-ensemble intégré de jQuery d'Angular, appelé" jQuery lite "ou jqLite.". Citation de: docs.angularjs.org/api/ng/function/angular.element . jqLite contient find ().
Kmaczek