programmatically apply a directive

7,933 views
Skip to first unread message

Tony pee

unread,
Dec 12, 2013, 6:29:55 PM12/12/13
to ang...@googlegroups.com
I am using the sf-virtual-repeat directive for scrolling, but it doesn't work in ie8. The easiest fix would be to fall back to using ng-repeat for ie8, and paginate. 

How could I decide which directive to apply to my <li>?

I was thinking an extra directive could choose and re-compile or something? Any ideas? 



--
Tony Polinelli


Sander Elias

unread,
Dec 13, 2013, 1:21:04 AM12/13/13
to ang...@googlegroups.com
Hi Tony,

have a look at ng-include. You can create a util/setting function to decide what to include.

Regards
Sander

Tony pee

unread,
Dec 13, 2013, 6:18:53 AM12/13/13
to ang...@googlegroups.com
Im not sure i want to use this tho as it would look like:

<script id="template" type="text/template">
.. item content ...
</script>

<ul ng-if="isIE8()>
   <li ng-repeat="d in data"><span ng-include="template" /></li>
</ul>

<ul ng-if="!isIE8()>
   <li sf-virtual-scroller="d in data"><span ng-include="template" /></li>
</ul>

This is my best option so far - but it seems messy, and perhaps less performant, using an ng-include inside the repeater. Also having 2 uls isnt ideal. (i need 2 as you cant have ng-if and ng-repeat on the same node. I was hoping that there might be a way to programatically assign a directive?




--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to angular+u...@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/groups/opt_out.



--
Tony Polinelli

Sander Elias

unread,
Dec 13, 2013, 6:55:21 AM12/13/13
to ang...@googlegroups.com

Hi Tony,

<ul ng-include="isIE8()? 'template using ngrepeat" : "template using sf-virtualscroller"''>
</ul>

Move the <li ...>..</li> inside the corresponding templates

Regards
Sander

Tony pee

unread,
Dec 13, 2013, 4:27:21 PM12/13/13
to ang...@googlegroups.com
interesting thanks, but this means that ALL of the template (unless i use another ng-include for the <li> too) - which isnt ideal - the li's content is currently about 30 lines, seems messy to duplicate 


--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to angular+u...@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/groups/opt_out.



--
Tony Polinelli

Daniel Tabuenca

unread,
Dec 13, 2013, 8:13:13 PM12/13/13
to ang...@googlegroups.com

So here is how you could programatically add a directive in a relatively clean way:

app.controller('MainCtrl', function($scope) {
  $scope.numbers=[1,2,3,4,5,6];
});

app.directive('myRepeat', function($compile){
  return  {
    //High priority means it will execute first
    priority: 5000,
    //Terminal prevents compilation of any other directive on first pass
    terminal: true,
    compile: function(element, attrs){
      //Add ng-repeat to the dom
      attrs.$set('ngRepeat', attrs.myRepeat);

      //Now that we added ng-repeat to the element, proceed with compilation
      //but skip directives with priority 5000 or above to avoid infinite 
      //recursion (we don't want to compile ourselves again)
      var compiled =  $compile(element, null, 5000);
      return function(scope){
        //When linking just delegate to the link function returned by the new 
        //compile
        compiled(scope);
      }
    }
  }
})

Used like this:

  <body ng-controller="MainCtrl">
    <ul>
    This list is generated by a "my-repeat" directive which just programatically adds 
    the ""ng-repeat" to the li.
      <li my-repeat="number in numbers">{{number}}</li>
    </ul>
  </body>

In this case this is just a simple use of the technique to illustrate how you could do it. I am just translating a “my-repeat” directive and adding an ‘ng-repeat’ directive dynamically with the same expression. You could obviously modify this example to suit your needs by adding different directive attributes depending on the values of certain conditions.

The code above has the following benefits:

  • Nothing is recompiled (we simply pause compilation, alter dom and then continue where we left off
  • No crazy manipulation or cloning of dom (I’ve seen people attempt this where they use clone functions or transclude things weird, the dom here is untouched (other than adding attributes to it)
  • The original directive’s attribute remains in the dom so you can see it.

I’ve tried to comment the code to explain what it’s doing, but there might be some advanced topics there that may not be familiar to you unless you are very experienced with directives.

Let me know if you want me to explain

Here is the plunkr to play with:

http://plnkr.co/edit/6jqeFiuaNhmk2YdJp2Sd?p=preview

Tony pee

unread,
Dec 15, 2013, 6:23:02 AM12/15/13
to ang...@googlegroups.com
Thanks so much - this is exactly what i was looking for! cheers


--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to angular+u...@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/groups/opt_out.



--
Tony Polinelli

Joseph Orbegoso Pea

unread,
Apr 5, 2014, 12:30:31 AM4/5/14
to ang...@googlegroups.com
Hi, would you guys please provide ideas on my new proposed API to make programmatically adding directives a simpler process? github.com/angular/angular.js/issues/6950 There's clearly a need for this in AngularJS. Thanks! 

Matúš Lešťan

unread,
Mar 3, 2015, 3:15:01 AM3/3/15
to ang...@googlegroups.com
You sir, deserve a gold medal for this, thanks you SO much!!

Danial Lokman

unread,
Mar 15, 2015, 5:25:23 AM3/15/15
to ang...@googlegroups.com
Here's a super easy article on 'Dynamically Compile and Add a custom directive in AngularJs' with snapshots. http://www.learn-angularjs-apps-projects.com/AngularJs/dynamically-add-directives-in-angularjs
Reply all
Reply to author
Forward
0 new messages