Search code examples
javascriptangularjsangular-directiveangularjs-module

Multiple partial views on AngularJS


I have an AngularJS application that has a list of contents on the menu. When the user clicks on an item on the menu, the content loads on the main view. There are multiple content types:

App wireframe

When "1" is clicked, a video is loaded. When "2" is clicked, a PDF document is loaded, and so on. Content types may repeat and be complex.

Now, I am setting $scope.content when an item is clicked and, depending on its contentType, I'm calling a different directive:

<div class="content" ng-switch on="content.contentType">
    <div ng-switch-when="video">
        <videoplayer-directive video="content"></videoplayer-directive>
    </div>
    <div ng-switch-when="pdf">
        <pdfreader-directive pdf="content"></pdfreader-directive>
    </div>
    <div ng-switch-when="...">
        <...-directive content="content"></...-directive>
    </div>
</div>

Now I have two problems:

  1. When the page is loaded, all the directive templates are automatically loaded. Even if I don't have a PDF in the menu, the pdf template and scripts will be loaded.
  2. Searching for it, I learned that directives should be tiny, not entire modules of my app.

How do I rewrite the switch above so I can comply with the best practices and load the templates and scripts only when needed?


Solution

  • This is exactly what UI-Router is for: Angular UI Router

    Decent tutorial on scotch.io

    An easier drop-in replacement for your code may be to simply use ng-if. Ng-if won't instantiate the directive until it's called. Just make sure that your directives aren't transcluding the outer div- if that's the case, shut transclusion off, or add another div to wrap them.

    <div class="content">
    <div ng-if="content.contentType=='video'">
        <videoplayer-directive video="content"></videoplayer-directive>
    </div>
    <div ng-if="content.contentType=='pdf'">
        <pdfreader-directive pdf="content"></pdfreader-directive>
    </div>
    <div ng-if="content.contentType=='...'">
        <...-directive content="content"></...-directive>
    </div>
    </div>