in angularjs come accedere all'elemento che ha attivato l'evento?


93

Uso sia Bootstrap che AngularJS nella mia app web. Ho qualche difficoltà a far lavorare i due insieme.

Ho un elemento, che ha l'attributo data-provide="typeahead"

<input id="searchText" ng-model="searchText" type="text"
       class="input-medium search-query" placeholder="title"
       data-provide="typeahead" ng-change="updateTypeahead()" />

E voglio aggiornare l' data-sourceattributo quando l'utente inserisce nel campo. La funzione updateTypeaheadè attivata correttamente, ma non ho accesso all'elemento che ha attivato l'evento, a meno che non utilizzi $('#searchText'), che è il modo jQuery, non il modo AngularJS.

Qual è il modo migliore per far funzionare AngularJS con il modulo JS vecchio stile.

Risposte:


60
 updateTypeahead(this)

non passerà l'elemento DOM alla funzione updateTypeahead(this). Qui si thisfarà riferimento all'ambito. Se vuoi accedere all'elemento DOM usa updateTypeahead($event). Nella funzione di callback puoi ottenere l'elemento DOM da event.target.

Nota: la funzione ng-change non consente di passare $ event come variabile.


65
ng-change non supporta il passaggio dell'oggetto evento $ evento come parametro.
Mark Rajcok

1
ng-style non supporta neanche a quanto pare.
laggingreflex

4
Downvoted anche. Non funziona per ng-class. $ event non è stato definito! <li ng-repeat="item in items" role="menuitem" ng-class="{\'selected\' : isSelected($event, item)}">
Saad Benbouzid

4
Sì, beh, non risponde davvero alla domanda, poiché $ event non funziona con ng-change: /
Adrian Tombu

1
probabilmente la risposta più sopravvalutata mai vista su SO
MatteoSp

74

Il modo angolare generale per ottenere l'accesso a un elemento che ha attivato un evento è scrivere una direttiva e bind () all'evento desiderato:

app.directive('myChange', function() {
  return function(scope, element) {
    element.bind('change', function() {
      alert('change on ' + element);
    });
  };
});

o con DDO (come da commento di @ tpartee di seguito):

app.directive('myChange', function() {
  return { 
    link:  function link(scope, element) {
      element.bind('change', function() {
        alert('change on ' + element);
      });
    }
  }
});

La direttiva di cui sopra può essere utilizzata come segue:

<input id="searchText" ng-model="searchText" type="text" my-change>

Plunker .

Digita nel campo di testo, quindi lascia / sfoca. La funzione di callback di modifica verrà attivata. All'interno di quella funzione di callback, hai accesso a element.

Alcune direttive incorporate supportano il passaggio di un oggetto $ event. Ad esempio, ng- * clic, ng-Mouse *. Nota che ng-change non supporta questo evento.

Sebbene sia possibile ottenere l'elemento tramite l'oggetto $ event:

<button ng-click="clickit($event)">Hello</button>

$scope.clickit = function(e) {
    var elem = angular.element(e.srcElement);
    ...

questo va "in profondità contro la via angolare" - Misko .


Sebbene la tua soluzione funzioni, non usa il formato DDO, il che rende molto, molto confuso capire come aggiungere / passare l'ambito al binding. Non c'è un modo semplice dal tuo esempio per aggiungere semplicemente un po 'di zucchero DDO per lo scoping e questo sembra altrettanto profondamente "contro il modo angolare" come passare $ event da un ng-click. Infatti nella documentazione ufficiale di Angular e negli esempi di codice, non ho trovato un solo esempio sintatticamente simile al tuo (cioè una direttiva che restituisce solo una funzione anonima senza alcun DDO).
tpartee

@tpartee, buoni punti. Quando originariamente ho scritto questa risposta, i documenti angolari avevano esempi di semplici direttive che restituivano solo una funzione anonima (che è la funzione di collegamento). Sono d'accordo che un DDO sarebbe meglio in questi giorni. Ho aggiornato la risposta.
Mark Rajcok

Penso che <button ng-click = "clickit ($ event.srcElement)"> sarebbe meglio
Carlos ABS

1
Col passare del tempo, sono sempre più convinto che "la via angolare" sia sovra-architettata e complicata
Jacob Stamm

7

puoi ottenere facilmente come questo primo evento di scrittura sull'elemento

ng-focus="myfunction(this)"

e nel tuo file js come sotto

$scope.myfunction= function (msg, $event) {
    var el = event.target
    console.log(el);
}

Anch'io l'ho usato.


8
questo restituisce l'ambito, quindi non funzionerà come previsto.
vdclouis

1
Questo non risolve affatto il problema dell'OP. Certo, consente a una funzione di sapere chi è il chiamato, ma ciò non ha alcuna relazione con la chiamata ng-change e non c'è connessione tra i due. Ciò di cui l'OP ha bisogno è essere in grado di fare riferimento all'elemento che ha attivato l'evento ng-change all'interno della chiamata di funzione che effettua.
tpartee

Funziona aggiungendo gli attributi (ad esempio, id): alert (event.target.id).
Weihui Guo

2

Esiste una soluzione che utilizza $ element nel controller se non si desidera creare un'altra direttiva per questo problema:

appControllers.controller('YourCtrl', ['$scope', '$timeout', '$element',
        function($scope, $timeout, $element) {

    $scope.updateTypeahead = function() {
       // ... some logic here
       $timeout(function() {
           $element[0].getElementsByClassName('search-query')[0].focus();
           // if you have unique id you can use $window instead of $element:
           // $window.document.getElementById('searchText').focus();
       });
    }
}]);

E questo funzionerà con ng-change :

<input id="searchText" type="text" class="search-query" ng-change="updateTypeahead()" ng-model="searchText" />

0

se vuoi il valore ng-model, se puoi scrivere in questo modo nell'evento attivato: $ scope.searchText


0

Non sono sicuro di quale versione avessi, ma questa domanda è stata posta molto tempo fa. Attualmente con Angular 1.5, posso utilizzare l' ng-keypressevento e la debouncefunzione di Lodash per emulare comportamenti simili come ng-change, in modo da poter catturare l'evento $

<input type="text" ng-keypress="edit($event)" ng-model="myModel">

$ scope.edit = _.debounce (function ($ event) {console.log ("$ event", $ event)}, 800)


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.