5

I'm trying to create a directive that would enhance an HTML element. So I managed to get the directive to run and to be associated with the element My current code is something like this:

angular.module('myModule', [])

    .directive('myDirective', function() {
        return {
            restrict: 'C',
            replace: false,
            scope: {},
            link: function(scope, element, attrs) {

            }
        }
    });

Now I would like to add new methods to the HTML element, for example I would like to do this:

// Pseudo code
myElement.reset();
myElement.reload(); // etc.

What would be the best way to add these methods to the directive?

laurent
  • 88,262
  • 77
  • 290
  • 428
  • 1
    It's not clear to me what you really want to do, but you don't put functions on the HTML element in angular. A natural place to define the functions might be in the directive controller and then expose them through the directive $scope, or maybe the controller itself - it really depends on what you want to do. – joakimbl Apr 16 '13 at 07:22
  • 1
    More or less the same question as mine http://stackoverflow.com/questions/34682739/initialising-and-re-initialising-a-component-in-angularjs. I'm still looking for a satisfactory answer. If Artem's answer is the "Angular way", then the Angular way is not a very nice way. – poshest Aug 17 '16 at 12:23

3 Answers3

6

Adding new methods to elements is not the Angular way. The angular way would be creating object with fields, passing it to directive and watch for field changes inside directive. Here is simple example: http://plnkr.co/edit/5v5mN69Bu18jpnoGwYqj?p=preview

Artem
  • 784
  • 8
  • 11
3

Your example of your directive is very basic, so I can't see what do you want to achieve. At least I can say: You can define new functions as functions of the scope , e.g.

...
link: function(scope, element, attrs) {
    scope.reset = function() {
         // reset something
    }
    // ...
}

If you want to access data loaded (e.g. for use in function reload()) in the scope you should write a controller for this use. so you can inject a service as a data source. Implementing functions bound to elements directly is more the jQuery way to do not the angularjs one. In angularjs you work with scopes mainly.

Maybe you provide a more complete example at best using jsfiddle or plnkr, I think it easier to help to see your use case or your problem as a piece of working code.

Lutz
  • 56
  • 2
  • 2
    I don't get it; according to this answer: http://stackoverflow.com/a/15681173/1641941 it's bad to pollute the scope with functions that belong to your directive but I have yet to find out where to add them and how to call them. This and the other answer popped up in a google search but don't answer my question. – HMR Jun 30 '14 at 08:00
  • @HMR don't worry about polluting the scope, because you have `scope: {}` the directive has an isolated scope. You can add functions to the scope in either the link or the controller. – John Henckel Mar 22 '17 at 21:01
0

One way to add these methods to your directive is to make the directive a controller (aka a subview). The $scope param in the controller will give you bi-directional access to the HTML in the template:

For example:

.directive("myDirective", function() {

var controller = ['$scope', function teamCountCtrl ($scope)
{
    $scope.reset = function() {
       // modify $scope.obj
    };

    $scope.reload = function() {
       // modify $scope.obj
    };
}];

return {
    replace: true,
    templateUrl: 'js/directives/teamCount.html',
    scope: {
        obj: '='
    },
    controller: controller
}});

Then in the template HTML you can call reset() or reload():

<div>

<a tabindex=-1 class="btn" href="#" ng-click="reset()">
    <i class="fa fa-fw"></i>
</a>

<a tabindex=-1 class="btn" href="#" ng-click="reload()">
    <i class="fa fa-fw"></i>
</a>

paiego
  • 3,619
  • 34
  • 43