3

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?

Community
  • 1
  • 1
Leo Lozes
  • 1,358
  • 1
  • 15
  • 33

2 Answers2

3

It can be achieved combining named views and abstract states. The 'key' here is to define an abstract state with a view for the layout (or generic template, if we follow the nomenclature of your original post).

Abstract state:

  .state('master', {
      abstract:  true,
      views: {
        generic_template: {
          templateUrl: 'genericTemplate.html'
        }
      }
    })

Then, you have to set this abstract state as parent to the child views. So, the child view will inherit the generic template view. Example:

.state('one', {
    url: '/one',
    templateUrl: 'one.html',
    parent: 'master'
})

In your index.html, you have to use a named view for the generic template, and inside it, another unnamed view. Something like this:

<body>

  <div ui-view="generic_template">
    <div ui-view></div>
  </div>

</body>

Here is a plunker with a complete working example. Hope it helps.

Leo Lozes
  • 1,358
  • 1
  • 15
  • 33
Xavi Torrens
  • 337
  • 1
  • 12
2

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

Henrik
  • 4,254
  • 15
  • 28
  • Thanks! This seems to be it! I've added a working plunker demonstrating that it works. We'll try to implement it in our project ASAP and let you know. – Leo Lozes Feb 08 '16 at 18:25
  • This is definitely the best choice. I was also trying to implement it with a transcluded directive, but without success. Thanks so much! – troig Feb 08 '16 at 18:37