6

I have an custom event core-transitionend (actually fired by Polymer), and I can set an event handler using document.addEventListener(). But what's the best practice to do it in AngularJS?

Or, I can explicitly set a handler in DOM, i.e. <paper-ripple on-core-transitionend="enter()"></paper-ripple>, but how to define this function in AngularJS?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Melkor
  • 532
  • 8
  • 25
  • create a directive which binds the event to element – Naeem Shaikh Dec 18 '14 at 14:10
  • @NaeemShaikh I've seen lots of posts and directive tutorials but I'm still not sure how to implement it. What does directives do here? How to pass event arguments? – Melkor Dec 18 '14 at 14:29

2 Answers2

7

see this fiddle, here I have created a custom directive which binds the event to the element,

angular.module('HelloApp', [])
    .directive('customDir', function () {
        return {
            restrict: 'A',

            link: function(scope, element, attrs)      
            {
                element.bind("click",function()
            {
            alert("you clicked me");

        })
            }    


        }
    })

In your case you can simply bind your defined event to the element

Naeem Shaikh
  • 15,331
  • 6
  • 50
  • 88
  • Thank you soooo much! I didn't understand `directive` until seeing your answer! – Melkor Dec 20 '14 at 07:51
  • @Melkor For less events this will work, but what you will do if you have 20 or 30 event handlers you wanna bind, you will create a custom directive for each of them? – Walid Ammar Dec 20 '14 at 08:35
1

You could do the following:

  1. Wrap your custom element inside an auto-binding template.
  2. Bind all handlers from angular scope to polymer scope (template element).

And that's it!

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<link href="https://www.polymer-project.org/components/polymer/polymer.html" rel="import">

<link href="https://www.polymer-project.org/components/paper-button/paper-button.html" rel="import">
<div ng-app="demo-app">
  <div ng-controller="DemoController">
    <template bind-events="clickMe,mouseOver" is="auto-binding">
      <paper-button raised on-tap="{{clickMe}}" on-mouseover="{{mouseOver}}">click me</paper-button>
    </template>
    <pre>
            <code>
            {[{text}]}
            </code>
            </pre>
  </div>
</div>
<script>
  angular.module('demo-app', [])
    .config(function($interpolateProvider) {
      $interpolateProvider.startSymbol('{[{').endSymbol('}]}');
    })
    .directive('bindEvents', function() {
      return {
        restrict: 'A',
        link: function(scope, element, attrs) {
          eventNames = attrs.bindEvents.split(',');
          eventNames.forEach(function(eventName) {
            element[0][eventName] = scope[eventName];
          });
        }
      }
    })
    .controller('DemoController', function($scope) {
      $scope.text = '';
      $scope.clickMe = function() {
        $scope.text += '\nyou clicked me!!';
        $scope.$apply();
      };
      $scope.mouseOver = function() {
        $scope.text += '\nyou hovered me!!';
        $scope.$apply();
      }
    });
</script>

Or if it's not an issue to copy the whole scope you can:

    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    <link href="https://www.polymer-project.org/components/polymer/polymer.html" rel="import">

    <link href="https://www.polymer-project.org/components/paper-button/paper-button.html" rel="import">
    <div ng-app="demo-app">
      <div ng-controller="DemoController">
        <template bind-angular-scope is="auto-binding">
          <paper-button raised on-tap="{{clickMe}}" on-mouseover="{{mouseOver}}">click me</paper-button>
        </template>
        <pre>
                <code>
                {[{text}]}
                </code>
                </pre>
      </div>
    </div>
    <script>
      angular.module('demo-app', [])
        .config(function($interpolateProvider) {
          $interpolateProvider.startSymbol('{[{').endSymbol('}]}');
        })
        .directive('bindAngularScope', function() {
         return {
                restrict: 'A',
                link: function(scope, element, attrs) {
                    for(k in scope) {
                     if (!element[0][k]) {
                      element[0][k] = scope[k];
                     }
                    }
                }
            }
        })
        .controller('DemoController', function($scope) {
          $scope.text = '';
          $scope.clickMe = function() {
            $scope.text += '\nyou clicked me!!';
            $scope.$apply();
          };
          $scope.mouseOver = function() {
            $scope.text += '\nyou hovered me!!';
            $scope.$apply();
          }
        });
    </script>

Notice: that I had to change Angular's interpolation symbol to get them to work together.

Walid Ammar
  • 4,038
  • 3
  • 25
  • 48
  • Thank you all the same, but the thing is, I have to change the interpolation markup, which is less simpler than Naeem's answer. – Melkor Dec 20 '14 at 07:53