angularjsでイベントをトリガーした要素にアクセスする方法は?


93

私のウェブアプリでは、BootstrapとAngularJSの両方を使用しています。2つを一緒に動作させるのに少し問題があります。

属性を持つ要素があります data-provide="typeahead"

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

またdata-source、ユーザーがフィールドに入力したときに属性を更新したいと思います。関数updateTypeaheadは正しくトリガーされますが$('#searchText')、AngularJSの方法ではなくjQueryの方法であるを使用しない限り、イベントをトリガーした要素にアクセスできません。

AngularJSを古いスタイルのJSモジュールで動作させる最良の方法は何ですか。

回答:


60
 updateTypeahead(this)

DOM要素を関数に渡しませんupdateTypeahead(this)。ここでthisはスコープを参照します。DOM要素にアクセスする場合は、を使用しますupdateTypeahead($event)。コールバック関数では、によってDOM要素を取得できますevent.target

注意:ng-change関数は$ eventを変数として渡すことができません。


65
ng-changeは、パラメーターとして渡されるイベントオブジェクト$ eventをサポートしていません。
Mark Rajcok、2013

1
ng-styleもサポートしていないようです。
laggingreflex 2014

4
反対票も投じた。ng-classでは機能しません。$ eventが未定義になりました!<li ng-repeat="item in items" role="menuitem" ng-class="{\'selected\' : isSelected($event, item)}">
Saad Benbouzid、2016

4
ええ、ええ、$ eventはng-changeで動作しないので、実際には質問には答えません:/
Adrian Tombu

1
SOでこれまでに見られた中で最も過大評価された回答
MatteoSp '18

74

イベントをトリガーした要素にアクセスする一般的なAngularの方法は、目的のイベントにディレクティブとbind()を書き込むことです。

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

またはDDOを使用(@tparteeのコメントに従って):

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

上記のディレクティブは次のように使用できます。

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

プランカー

テキストフィールドに入力し、そのままにするかぼかします。変更コールバック関数が起動します。そのコールバック関数内では、にアクセスできますelement

一部の組み込みディレクティブは、$ eventオブジェクトの受け渡しをサポートしています。たとえば、ng- * click、ng-Mouse *。ng-changeはこのイベントをサポートしないことに注意してください。

$ eventオブジェクトを介して要素を取得できますが、

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

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

これは「Angular wayに対して深い」-Miskoです。


ソリューションはある程度機能しますが、DDO形式を使用しないため、バインディングにスコープを追加/渡す方法を理解するのが非常に難しくなります。あなたの例からスコーピング用のDDO糖を単純に追加する単純な方法はありません。これは、ng-clickから$ eventを渡すのと同じくらい「Angularの方法」と同じように見えます。実際、Angularの公式ドキュメントとコード例では、構文的に似ている例(DDOなしで匿名関数のみを返すディレクティブなど)を見つけることができませんでした。
tpartee 2016

@tpartee、良い点。私が最初にこの回答を書いたとき、角度付きドキュメントには、匿名関数(リンク関数)を返すだけの単純なディレクティブの例が含まれていました。最近は、DDOの方が優れていることに同意します。答えを更新しました。
Mark Rajcok

<button ng-click = "clickit($ event.srcElement)">のほうがいいと思います
Carlos ABS

1
時が経つにつれ、「角度の方法」は過剰に構築され、複雑になっていると私はますます確信しています
Jacob Stamm

7

要素のこの最初の書き込みイベントのように簡単に取得できます

ng-focus="myfunction(this)"

そしてあなたのjsファイルで以下のように

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

私もそれを使用しました。


8
これはスコープを返すため、期待どおりに動作しません。
vdclouis 2015年

1
これは、OPの問題をまったく解決しません。確かに、それは1つの関数に呼び出された人が誰であるかを知らせますが、それはng-change呼び出しとは関係がなく、2つの間に接続はありません。OPに必要なのは、OPが行う関数呼び出し内でng-changeイベントをトリガーした要素を参照できるようにすることです。
tpartee 2016

これは、属性(たとえば、id)を追加することによって機能します:alert(event.target.id)。
Weihui Guo 2017

2

この問題に対して別のディレクティブを作成したくない場合は、コントローラーで$ elementを使用する解決策があります。

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

そして、これはng-changeで動作します

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

0

ng-model値が必要な場合、トリガーされたイベントで次のように記述できる場合:$ scope.searchText


0

お使いのバージョンはわかりませんが、この質問はずっと前に尋ねられました。現在Angular 1.5では、Lodashのng-keypressイベントとdebounce関数を使用して、のような同様の動作をエミュレートできるため、$ eventをキャプチャできますng-change

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

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


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.