di angularjs bagaimana cara mengakses elemen yang memicu acara tersebut?

93

Saya menggunakan Bootstrap dan AngularJS di aplikasi web saya. Saya mengalami kesulitan untuk membuat keduanya bekerja sama.

Saya memiliki elemen, yang memiliki atribut data-provide="typeahead"

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

Dan saya ingin memperbarui data-sourceatribut ketika pengguna memasukkan di lapangan. Fungsinya updateTypeaheaddipicu dengan benar, tetapi saya tidak memiliki akses ke elemen yang memicu acara tersebut, kecuali saya menggunakan $('#searchText'), yang merupakan cara jQuery, bukan cara AngularJS.

Apa cara terbaik untuk membuat AngularJS bekerja dengan modul JS gaya lama.

David S.
sumber

Jawaban:

60
 updateTypeahead(this)

tidak akan meneruskan elemen DOM ke fungsi updateTypeahead(this). Di sini thisakan mengacu pada ruang lingkup. Jika Anda ingin mengakses gunakan elemen DOM updateTypeahead($event). Dalam fungsi callback Anda bisa mendapatkan elemen DOM dengan event.target.

Harap Catatan: fungsi ng-change tidak memungkinkan untuk melewatkan $ event sebagai variabel.

Mahbub
sumber
65
ng-change tidak mendukung objek acara $ event yang diteruskan sebagai parameter.
Mark Rajcok
1
ng-style sepertinya tidak mendukung.
laggingreflex
4
Juga tidak disukai. Tidak berfungsi untuk ng-class. $ acara tidak ditentukan! <li ng-repeat="item in items" role="menuitem" ng-class="{\'selected\' : isSelected($event, item)}">
Saad Benbouzid
4
Ya, tidak benar-benar menjawab pertanyaan itu, karena $ event tidak berfungsi dengan ng-change: /
Adrian Tombu
1
mungkin jawaban dengan rating tertinggi yang pernah ada di SO
MatteoSp
74

Cara Angular umum untuk mendapatkan akses ke elemen yang memicu peristiwa adalah dengan menulis direktif dan bind () ke acara yang diinginkan:

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

atau dengan DDO (sesuai komentar @ tpartee di bawah):

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

Arahan di atas dapat digunakan sebagai berikut:

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

Plunker .

Ketik di kolom teks, lalu biarkan / buram. Fungsi ubah panggilan balik akan aktif. Di dalam fungsi panggilan balik itu, Anda memiliki akses ke element.

Beberapa direktif bawaan mendukung penerusan objek $ event. Misalnya, ng- * klik, ng-Mouse *. Perhatikan bahwa ng-change tidak mendukung acara ini.

Meskipun Anda bisa mendapatkan elemen melalui objek $ event:

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

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

ini berjalan "jauh berlawanan dengan cara Angular" - Misko .

Mark Rajcok
sumber
Meskipun solusi Anda berfungsi, ia tidak menggunakan format DDO, yang membuatnya sangat, sangat membingungkan untuk mengetahui cara menambahkan / meneruskan cakupan ke pengikatan. Tidak ada cara sederhana dari contoh Anda untuk hanya menambahkan beberapa gula DDO untuk pelingkupan dan itu tampaknya sama "berlawanan dengan cara Angular" seperti melewatkan $ event dari ng-click. Faktanya dalam dokumentasi resmi Angular dan contoh kode, saya tidak dapat menemukan satu contoh pun yang secara sintaksis mirip dengan milik Anda (yaitu, perintah yang hanya mengembalikan fungsi anonim tanpa DDO).
tpartee
@ partee, poin bagus. Kembali ketika saya pertama kali menulis jawaban ini, dokumen sudut memang memiliki contoh arahan sederhana yang baru saja mengembalikan fungsi anonim (yang merupakan fungsi tautan). Saya setuju bahwa DDO akan lebih baik hari ini. Saya memperbarui jawabannya.
Mark Rajcok
Saya pikir <button ng-click = "clickit ($ event.srcElement)"> akan lebih baik
Carlos ABS
1
Seiring berjalannya waktu, saya semakin yakin bahwa "cara Sudut" terlalu ketat dan rumit
Jacob Stamm
7

Anda bisa mendapatkan dengan mudah seperti acara tulis pertama pada elemen ini

ng-focus="myfunction(this)"

dan di file js Anda seperti di bawah ini

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

Saya telah menggunakannya juga.


sumber
8
ini mengembalikan ruang lingkup, jadi ini tidak akan berfungsi seperti yang diharapkan.
vdclouis
1
Ini sama sekali tidak menyelesaikan masalah OP. Tentu itu memungkinkan satu fungsi mengetahui siapa yang dipanggil, tetapi itu tidak ada hubungannya dengan panggilan ng-change dan tidak ada hubungan antara keduanya. Apa yang dibutuhkan OP adalah untuk dapat mereferensikan elemen yang memicu kejadian ng-change dalam pemanggilan fungsi yang dibuatnya.
tpartee
Ini bekerja dengan menambahkan atribut (katakanlah, id): alert (event.target.id).
Weihui Guo
2

Ada solusi menggunakan $ element di controller jika Anda tidak ingin membuat direktif lain untuk masalah ini:

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

Dan ini akan bekerja dengan ng-change :

<input id="searchText" type="text" class="search-query" ng-change="updateTypeahead()" ng-model="searchText" />
Tomasz Górka
sumber
0

jika Anda ingin ng-model value, jika Anda dapat menulis seperti ini di event yang dipicu: $ scope.searchText

dylan
sumber
0

Saya tidak yakin versi mana yang Anda miliki, tetapi pertanyaan ini sudah lama ditanyakan. Saat ini dengan Angular 1.5, saya dapat menggunakan ng-keypressacara dan debouncefungsi dari Lodash untuk meniru perilaku serupa ng-change, jadi saya dapat menangkap $ event

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

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

Telvin Nguyen
sumber
-2

Untuk meneruskan elemen sumber di Angular 5:

<input #myInput type="text" (change)="someFunction(myInput)">

Jasper
sumber
1
pertanyaannya adalah untuk angularjs (1)
Mizanur Rahman Mojumder