web-dev-qa-db-ja.com

ng-clickで$ eventを自動的に渡しますか?

ng-clickオブジェクトを次のように渡すと、$eventからクリックイベントにアクセスできることがわかります。

<button ng-click="myFunction($event)">Give me the $event</button>

<script>
  function myFunction (event) {
    typeof event !== "undefined" // true
  }
</script>

$eventを毎回明示的に渡す必要があるのは少し面倒です。 ng-clickをデフォルトで何らかの形で関数に渡すように設定することは可能ですか?

67
Elise

ng-clickディレクティブのソースを覗いてください:

...
compile: function($element, attr) {
  var fn = $parse(attr[directiveName]);
  return function(scope, element, attr) {
    element.on(lowercase(name), function(event) {
      scope.$apply(function() {
        fn(scope, {$event:event});
      });
    });
  };
}

それが示すeventオブジェクトの方法渡されるng-click式に、$eventをパラメーターの名前として使用します。これは$ parseサービスによって行われます。このサービスでは、パラメータをbleed intoターゲットスコープに許可しません。つまり、答えはno$eventオブジェクトにアクセスするには、コールバックパラメーターを使用する必要があります。

63
Stewie

$eventng-clickに追加します。例:

<button type="button" ng-click="saveOffer($event)" accesskey="S"></button>

次に、jQuery.Eventがコールバックに渡されました。

enter image description here

36
Jeff Tian

他の人が言ったように、実際にあなたが求めていることを厳密に行うことはできません。そうは言っても、angularフレームワークで利用できるツールはすべて実際に利用できます!つまり、実際に独自の要素を記述して、この機能を自分で提供できるということです。これらの1つを、次のplunkrで見ることができる例として書きました( http://plnkr.co/edit/Qrz9zFjc7Ud6KQoNMEI1 )。

これの重要な部分は、「クリック可能な」要素を定義することです(古いIEサポートが必要な場合はこれを行わないでください)。次のようなコードで:

<clickable>
  <h1>Hello World!</h1>
</clickable>

次に、このクリック可能な要素を取得して、必要なもの(クリックイベントを自動的に設定するもの)に変換するディレクティブを定義しました。

app.directive('clickable', function() {
    return {
        transclude: true,
        restrict: 'E',
        template: '<div ng-transclude ng-click="handleClick($event)"></div>'
    };
});

最後に、コントローラーにクリックイベントを用意します。

$scope.handleClick = function($event) {
    var i = 0;
};

さて、クリックイベントを処理するメソッドの名前をハードコードすることを述べる価値があります。これを排除したい場合は、クリックハンドラの名前と「tada」をディレクティブに指定できる必要があります。使用できる要素(または属性)があり、「$ event」を再度挿入する必要はありません。

お役に立てば幸いです!

11
drew_w

これを行うことはお勧めしませんが、ngClickディレクティブをオーバーライドして、探していることを実行できます。それは言っていない、あなたがすべきです。

元の実装を念頭に置いて:

compile: function($element, attr) {
  var fn = $parse(attr[directiveName]);
  return function(scope, element, attr) {
    element.on(lowercase(name), function(event) {
      scope.$apply(function() {
        fn(scope, {$event:event});
      });
    });
  };
}

これをオーバーライドするためにこれを行うことができます:

// Go into your config block and inject $provide.
app.config(function ($provide) {

  // Decorate the ngClick directive.
  $provide.decorator('ngClickDirective', function ($delegate) {

    // Grab the actual directive from the returned $delegate array.
    var directive = $delegate[0];

    // Stow away the original compile function of the ngClick directive.
    var origCompile = directive.compile;

    // Overwrite the original compile function.
    directive.compile = function (el, attrs) {

      // Apply the original compile function. 
      origCompile.apply(this, arguments);

      // Return a new link function with our custom behaviour.
      return function (scope, el, attrs) {

        // Get the name of the passed in function. 
        var fn = attrs.ngClick;

        el.on('click', function (event) {
          scope.$apply(function () {

            // If no property on scope matches the passed in fn, return. 
            if (!scope[fn]) {
              return;
            }

            // Throw an error if we misused the new ngClick directive.
            if (typeof scope[fn] !== 'function') {
              throw new Error('Property ' + fn + ' is not a function on ' + scope);
            }

            // Call the passed in function with the event.
            scope[fn].call(null, event);

          });
        });          
      };
    };    

    return $delegate;
  });
});

次に、次のような関数を渡します。

<div ng-click="func"></div>

とは対照的に:

<div ng-click="func()"></div>

jsBinhttp://jsbin.com/piwafeke/3/edit

私が言ったように、私はnotこれを行うことをお勧めしますが、それはあなたを示す概念の証明です、はい-あなたは実際に上書き/拡張/増強することができます組み込みangular動作をニーズに合わせます。元の実装を深く掘り下げる必要はありません。

この道を進むことに決めた場合は、注意して使用してください(ただし、とても楽しいです)。

2
Kasper Lewau