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?

2
  • create a directive which binds the event to element Commented Dec 18, 2014 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? Commented Dec 18, 2014 at 14:29

2 Answers 2

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

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you soooo much! I didn't understand directive until seeing your answer!
@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?
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.

1 Comment

Thank you all the same, but the thing is, I have to change the interpolation markup, which is less simpler than Naeem's answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.