0

i wrote a function called getDepth(object) that gives me the depth of an object and then returns a string, for example if the depth of the object was 3 it will return the string "sub-sub-sub", and in my directive template i want to call that function from ng-class such as

'<span ng-class="getDepth(item)">{{item.content}}</span>'

but i am not sure where to put that function in my directive, should it just be inside the link function?

2 Answers 2

1

This is typically the job for a controller. So you can create an anonymous controller in your directive and place it there, or in the scope of the parent controller looking after this section of code - that is assuming of course one exists.

Maybe though you would like to reuse this functionality later in the app, so I recommend placing it high on the controller tree to allow others to inherit its function.

The linker functions job is strictly DOM manipulation, and this is not DOM manipulation this is a function returning a string and the ng-class directive in turn does the DOM manipulation.

If you check the docs:

Directives that want to modify the DOM typically use the link option. link takes a function with the following signature, function link(scope, element, attrs) { ... } where:

  .directive('myCurrentTime', function($interval, dateFilter) {

    function link(scope, element, attrs) {
      var format,
          timeoutId;

      function updateTime() {
        element.text(dateFilter(new Date(), format));
      }...

As you can see the link function is changing the DOM.

So to answer the question, this is how the directive should be structured.

app.directive('myDirective', function() {

    var controller = function($scope) {
      $scope.getDepth = function (item) {
          return "text-success";
        };    
    }

    return {
      template: '<span ng-class="getDepth(item)">{{item.content}}</span>',
      scope: {item: '='},
      controller: controller // or this can be the name of an outside reference controller as well - which i prefer for unit testing and reusability purposes. 
      }
    };
  }
]);
Sign up to request clarification or add additional context in comments.

Comments

0

if you want to let this control to your directive instead controller you can put it in the link function, an example directive should be like this...

app.directive('myDirective', ['$compile',
  function($compile) {
    return {
      template: '<span ng-class="getDepth(item)">{{item.content}}</span>',
      scope: {item: '=item'},
      link: function(scope, element, attrs) {
        scope.getDepth = function (item) {
          return "text-success";
        };
      }
    };
  }
]);

here is PLUNKER

5 Comments

thanks worked pretty well! isn't item: '=item' the same as item:'=' ?
yes same, I just fork it from another of my plunks that is why I used it like this, just change the variable name :D ... your way is shortcut...
This is unfortunately the incorrect use of the link function
@StenMuchow this isn't incorrect you can set function into the scope of directive in link or compile function. besides that if you look into my answer I said that 'if you want to let this control to your directive instead controller'. just look at the question, he is asking that where should I put it in my DIRECTIVE, so my answer is not incorrect as it is working perfect. of course it is not the best practice but please look at your solution and usage of controller. from angular doc : Best Practice: use controller when you want to expose an API to other DIRECTIVES. Otherwise use link.
Exactly - not best practice - and in the world of JS where there are a million ways to do things - we need to follow best practices so we are all on the same page. To me this kind of function to check the depth of nested elements could very easily be re-usable in other directives, so to code defensively - Pragmatic Programmers - shouldn't we realise this potential usage and factor it into a outside controller so we can in the future have easy access to re-usage of functionality - keeping our code as modular as possible?

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.