Search code examples
angularjstemplatesangular-ui-routerangular-materialnested-views

ui-router: intermediate templates


Final Edit: working plunker with the transcluded directive.

Edit: I made a first plunker with the solution given in the first answer. It works, but it's not the desired behaviour, because the template contains all the partial.

I made a second plunker with what I hope to achieve (but it doesn't work, obviously). I think it's mostly because the template is not the parent of the partial, but it is contained in it, so ui-router doesn't understand very well what I want.

Any help with this would be greatly appreciated!

We are building a website with Angular Material and ui-router, and all our content page share the same "container", because we always want the same responsive behaviour.

The code of this generic container would be something like:

  <div class="layout-content">
    <div layout="column" layout-align="center">
      <div layout="row" layout-align="center center">
        <section class="layout-fixed-width md-whiteframe-z1" flex-sm="100" flex-gt-sm="90">

        {{content placed here}}

        </section>
      </div>
    </div>
  </div>

The header can differ in all pages, so the structure we have would basically be:

enter image description here

The question is, how can this be achieved in ui-router? We have done some nested views, but I don't see how to do a generic template so the code could be something like:

<form>
  <md-toolbar/>
  <div ui-view="generic-template">
      <div ui-view="my-content"></div>
  </div>
</form>

Ideally we would want to define only one time the generic-template view, and use it in all our modules.

In the nested states and nested views documentation I see mostly nested state stuff, but what we want is really only a plain html template, so maybe we are over-complicating this, and an easier way is possible (I'm quite sure it's the case). I've also checked this issue, where one of the answers say that ui-router should be the solution, but not much more.

Maybe we should do a directive instead?


Solution

  • Maybe we should do a directive instead?

    A directive with a transcluded ui-view certainly seems to give you what you're looking for. This saves you from cluttering up your routing logic with something that has nothing to do with routing.

    genericTemplate.html:

    <div>
        <p>Generic content</p>
        <ng-transclude></ng-transclude>
    </div>
    

    Somewhere in your js:

    angular.module('formApp')
        .directive('genericTemplate', function () {
            return {
                replace: true,
                transclude: true,
                templateUrl: 'genericTemplate.html'
            };
        });
    

    In your html:

    <body ng-app='formApp'>
        <div generic-template>
            <div ui-view></div>
        </div>
    </body>
    

    Edit: working plunker