Wie wähle ich ein Element anhand des Klassennamens mit jqLite aus?

110

Ich versuche, jquery aus meiner Angular.js-App zu entfernen, um sie leichter zu machen, und stattdessen Angulars jqLite zu verwenden. Die App verwendet jedoch häufig find ('# id') und find ('.classname'), die von jqLite nicht unterstützt werden, sondern nur 'tag names' (gemäß Dokumentation).

Ich fragte mich, was Ihrer Meinung nach der beste Ansatz wäre, um es zu ändern. Ein Ansatz, über den ich nachgedacht habe, ist das Erstellen benutzerdefinierter HTML-Tags. Zum Beispiel: ändern
<span class="btn btn-large" id="add-to-bag">Add to bag</span>

zu

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

und

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

zu

$element.find('a2b')

Irgendwelche Gedanken? andere Ideen?

Vielen Dank

Lior

Lior
quelle
4
IDs müssen eindeutig sein, daher ist es nicht sinnvoll, ein Element, das einem anderen Element untergeordnet ist, anhand der ID zu finden. Wählen Sie einfach das Element anhand der ID aus. Wenn Ihre IDs nicht eindeutig sind, ändern Sie Ihre ID in eine Klasse. Sie können auch DomElement.querySelector(".myclassname")ein einzelnes dekendierendes Element mit einem CSS-Selektor oder alle übereinstimmenden Elemente auswählen, indem Sie Alle hinzufügen: DomElement.querySelectorAll(".myclassname")Das funktioniert natürlich nicht in IE <9.
Kevin B
Wenn Sie ein a2bElement definieren , müssen Sie eine Direktive definiert haben. Können Sie das tun, was in der Link-Funktion der Direktive zu tun ist, und daher die Notwendigkeit vermeiden, find () vollständig aufzurufen? Ähnlich wie bei Ihren Klassen - können Sie Direktiven definieren und die benötigte Funktionalität in die Verknüpfungs- (oder Kompilierungs-) Funktionen der Direktiven einfügen?
Mark Rajcok
2
@ KevinB Angulars jqLite soll "nur Tag-Namen" unterstützen
Lior
@ MarkRajcok Ich habe keine Direktive definiert. es scheint in IE und Chrome zu funktionieren. Aber selbst wenn ich eine Richtlinie definieren würde, warum würde sie helfen? Ich müsste immer noch ein DOM-Element beschaffen.
Lior
Wie kommt es, dass find ('span.btn') oder ähnliches bei Ihnen nicht funktioniert?
Fabi

Antworten:

202

Im Wesentlichen und wie von @ kevin-b angegeben:

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

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

Hinweis: Wenn Sie dies von Ihren Controllern aus tun möchten, sollten Sie sich den Abschnitt "Controller richtig verwenden" im Entwicklerhandbuch ansehen und Ihre Präsentationslogik in entsprechende Anweisungen umgestalten (z. B. <a2b ...>). .

psema4
quelle
3
Vielen Dank! Um aus der Antwort von Ricardo Bin (Mailingliste von Angular
Lior
Leider ist die angegebene URL nicht mehr gültig ( docs.angularjs.org/guide/dev_guide.mvc.understanding_controller ), und in diesem Abschnitt scheint es keinen Ersatz zu geben.
Per Quested Aronsson
Angular.element (document.querySelector ('# id')) ist die Alternative zu: $ ('# id'), nicht für: elementArray.find ('# id')
Broda Noel
Richtig - aber wie wir festgestellt haben, müssen wir beim Erstellen neuer Teile unserer Anwendung im Winkel manchmal ältere Teile für eine Weile "mit Klebeband" versehen, bis sie aktualisiert oder neu berücksichtigt werden können. In unserem Fall mussten wir einige alte jquery / ajax-Daten laden, ohne das vorhandene Durcheinander zu ändern, also haben wir Folgendes getan: $ http.get ('/ Task / GetTaskStatsByTaskId /' + taskId) .success (function (data) {angle.element (document.querySelector ('# userTasksContainer')). html (data);});
Kenn
42
Wenn elem ein jqlite-Objekt ist, wäre esangular.element(elem[0].querySelector('.classname'));
cleversprocket
2

angualr verwendet die leichtere Version von jquery namens jqlite, was bedeutet, dass es nicht alle Funktionen von jQuery bietet. Hier finden Sie eine Referenz in AngularJS-Dokumenten darüber, was Sie in jquery verwenden können. Angular Element docs

In Ihrem Fall müssen Sie ein div mit ID oder Klassennamen finden. für den Klassennamen können Sie verwenden

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

oder Sie können den Abfrageauswähler viel einfacher verwenden

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

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

es ist nicht so flexibel wie jQuery, aber was

hannad rehman
quelle
1

Wenn elem.find()dies bei Ihnen nicht funktioniert, überprüfen Sie, ob Sie das JQuery-Skript vor dem Winkelskript einschließen .

ancajic
quelle
3
Obwohl das OP speziell nach jqLite gefragt hat, kann diese Antwort sicherlich hilfreich sein, wenn Sie jQuery verwenden und erwarten, dass find () auch mit Klassen und IDs funktioniert.
Matt B
2
Zur Verdeutlichung: "Wenn jQuery verfügbar ist, ist angle.element ein Alias ​​für die jQuery-Funktion. Wenn jQuery nicht verfügbar ist, delegiert angle.element an Angulars integrierte Teilmenge von jQuery, die als" jQuery lite "oder jqLite bezeichnet wird." Zitat aus: docs.angularjs.org/api/ng/function/angular.element . jqLite enthält find ().
Kmaczek