AngularJS: ngInclude vs directive

23,150

It all depends on what you want from your code fragment. Personally, if the code doesn't have any logic, or doesn't even need a controller, then I go with ngInclude. I typically put large more "static" html fragments that I don't want cluttering up the view here. (ie: Let's say a large table whose data comes from the parent Controller anyway. It's cleaner to have <div ng-include="bigtable.html" /> than all those lines cluttering up the View)

If there is logic, DOM manipulation, or you need it to be customizable (aka render differently) in different instances it's used, then directives are the better choice (they're daunting at first, but they're very powerful, give it time).

ngInclude

Sometimes you will see ngInclude's that are affected by their exterior $scope / interface. Such as a large/complicated repeater lets say. These 2 interfaces are tied together because of this. If something in the main $scope changes, you must alter / change your logic within your included partial.

Directives

On the other hand, directives can have explicit scopes / controllers / etc. So if you're thinking of a scenario where you'd have to reuse something multiple times, you can see how having its own scope connected would make life easier & less confusing.

Also, anytime you are going to be interacting with the DOM at all, you should use a directive. This makes it better for testing, and decouples these actions away from a controller / service / etc, which is something you want!

Tip: Make sure not to use restrict: 'E' if you care about IE8! There are ways around this, but they are annoying. Just make life easier and stick with attribute/etc. <div my-directive />

Components [Update 3/1/2016]

Added in Angular 1.5, it's essentially a wrapper around .directve(). Component should be used most of the time. It removes a lot of boilerplate directive code, by defaulting to things like restrict: 'E', scope : {}, bindToController: true. I highly recommend using these for almost everything in your app, in order to be able to transition to Angular2 more easily.

In conclusion:

You should be creating Components & Directives a majority of the time.

  • More extensible
  • You can template and have your file externally (like ngInclude)
  • You can choose to use the parent scope, or it's own isolate scope within the directive.
  • Better re-use throughout your application


Update 3/1/2016

Now that Angular 2 is slowly wrapping up, and we know the general format (of course there will still be some changes here and there) just wanted to add how important it is to do components (sometimes directives if you need them to be restrict: 'E' for example).

Components are very similar to Angular 2's @Component. In this way we are encapsulating logic & html in the same area.


Make sure you encapsulate as many things as you can in components, it will make the transition to Angular 2 that much easier! (If you choose to make the transition)

Here's a nice article describing this migration process using directives (very similar if you were going to use components of course) : http://angular-tips.com/blog/2015/09/migrating-directives-to-angular-2/

Share:
23,150
EricC
Author by

EricC

Updated on July 08, 2022

Comments

  • EricC
    EricC almost 2 years

    I do not quite understand when to use a directive and when it would be more appropriate to use nginclude. Take this example: I have a partial, password-and-confirm-input-fields.html, that is the html for entering and confirming a password. I use this both under signup-page and under change-password-page. Those two pages has a controller each, the partial html has no dedicated controller.

    Should I use directive or ngInclude for this?

  • Jazzy
    Jazzy about 10 years
    I agree with this answer. The learning curve for directives is steep, but it really pays off once you get it.
  • EricC
    EricC about 10 years
    @mcpDESIGNS, one case that perhaps does not fit this answer perfectly (at least not the two first paragraphs). If I have a nav-partial, with its own controller, and I will only use this once (in the index.html-file), then this probably should be a partial and not a directive since it is used only once (it is kind of a separate app in the sense that it is not included as a part of the ngview), even if it has its own logic. Or?
  • Marwen Trabelsi
    Marwen Trabelsi about 9 years
    This is still confusing.. you can also specify a controller when using ngInclude, look at this : stackoverflow.com/questions/13811948/…
  • Mark Pieszak - Trilon.io
    Mark Pieszak - Trilon.io about 9 years
    Of course, but it's always completely connected to the parent controller in some way. Where a directive can create a controller within itself for when the template is loaded. It can be completely separate (if you want)
  • Arwin
    Arwin over 8 years
    My biggest problem with directives so far is with they way they are rendered: always. If I create a page with several tabs, I (often, not always) want that tab to be loaded and rendered only when it is shown. But directives are loaded immediately. It also makes them practically unusable for recursive applications (like treeviews). For these cases, includes seem to work much better.
  • Mark Pieszak - Trilon.io
    Mark Pieszak - Trilon.io over 8 years
    You can use ng-if to decide whether a directive should be rendered @Arwin unlike ng-show, ng-if doesn't let the underlying Angular code to be generated
  • Mark Pieszak - Trilon.io
    Mark Pieszak - Trilon.io over 8 years
    My apologies, that might not stop them from "loading" look at this implementation: stackoverflow.com/questions/14904139/… Basically you have to actually decide when to load the template with $http and $compile it. Forgot I use this same concept myself sometimes! @Arwin
  • Arwin
    Arwin over 8 years
    Exactly, that's my problem with them at the moment. I'd prefer a much more straightforward setting on the directive to control this.
  • Mark Pieszak - Trilon.io
    Mark Pieszak - Trilon.io over 8 years
    Best thing you can do is abstract this concept into a factory or something, that way you can just call it from within a link function and voila! It would of been nice baked into directives though, without a doubt :( @Arwin
  • netalex
    netalex over 7 years
    in your answeryou say that it's unsafe to use directive with "E" option in ie8. But in the update you said that components are defined with the "E" option in mind. That's the same with components or they have a workaround out of the box?
  • Mark Pieszak - Trilon.io
    Mark Pieszak - Trilon.io over 7 years
    @netalex I believe unfortunately if you're worried about IE8 then it'll still be a problem, yes it just defaults to the E option :( although IE8 was dropped at 1.3 so can't imagine there are many people still worried about that?