Sam
Sam

Reputation: 1331

Architecture for multi-page angular application

We have to design a angular multi-page application. And the pages look something like this:

enter image description here enter image description here

I planned to design the page in such a way that each section of the page will have a particular angular controller associated to it and a template will be defined which will be added via the ng-include directive. So basically the page 1 (route ==> '/') will have a 4 different sections which will have 4 different controllers.

Now ofcourse this works fine on a single page, but I am unsure how to define the routes here.

1) Should I have nested controllers, so for page 1 we have a page1Controller and all the other controllers will be under this. Will this be a good design?

or

2) Should I have one controller per page which will make the routing easy and have directives defined for each sections of the page?

Upvotes: 4

Views: 970

Answers (3)

Daniel Lizik
Daniel Lizik

Reputation: 3144

Going off Mike's answer I would define your route-level templates as single components that are high level layout containers.

.state('page1', {
  url: '/page1',
  template: '<page1></page1>'
})
.state('page2', {
  url: '/page2',
  template: '<page2></page2> 
});

Then in your <page> components (which just dictate layout of nested directives/components) you could do:

.component('page1', {
  template: [
    '<section1></section1>',
    '<section2></section2>',
    '<section3></section3>'
  ].join('')
});

Also I realize you wrote "multi page applicaton" which would suggest you don't plan on using a router at all. If that is the case your backend will have to take care of the dynamic layout generation, which is a totally different question.

Upvotes: 1

Gregori
Gregori

Reputation: 829

I would use directives to allow multiple controllers, to re-use code between page1 and page 2, and to prepare for the migration to Angular 2.

Your page would look like:

<section1></section1>
<section2></section2>
<section3></section3>
<section4></section4>

And you will have to write a directive per section:

module.directive('section1', function() {
  return {
    scope: {},
    bindToController: {
    },
    controller: function() { },
    controllerAs: 'vm',
    template: `
      <div>This is section1
      </div>
    `
  }
});

Here is an article to approximate module in Angular 1.x

If you are interested in using TypeScript, here is an tutorial that includes two pages with 2 shared sections using directives as explained above. Look at the section close to the end called 'Sample pages with shared directives.' The tutorial includes a github repository. In that tutorial, page1 looks like

h1 page1
page1-section1
page1-section2

And, the second page shared the same sections:

h1 page2
page2-section2
page2-section1

The controllers between page1 and page2 are very similar and creates the section tags using the same/shared directives (DigiSection1.Section1Directive):

angular
.module('digiangularjs.page1', [])
.controller('agendaController', Page1Controller)
.directive("page1Section1", [() => new DigiSection1.Section1Directive()])
.directive("page1Section2", [() => new DigiSection2.Section2Directive()])
;

And for the second page, we use the same directives, but

angular
.module('digiangularjs.page2', [])
.controller('page2Controller', Page2Controller)
.directive("page2Section1", [() => new DigiSection1.Section1Directive()])
.directive("page2Section2", [() => new DigiSection2.Section2Directive()])
;

Upvotes: 2

Mike Perrenoud
Mike Perrenoud

Reputation: 67898

I think I would recommend just using multiple named views. Each named view can have its own controller:

$stateProvider
  .state('home', {
    url: '/',
    views: {
      '': {
        templateUrl: 'templates/app.tpl.html',
      },
      'section1': {
        controller: 'Section1Controller as vm',
        templateUrl: 'templates/section1.tpl.html'
      },
      'section2': {
        controller: 'Section2Controller as vm',
        templateUrl: 'templates/section2.tpl.html'
      },
      'section3': {
        controller: 'Section3Controller as vm',
        templateUrl: 'templates/section3.tpl.html'
      },
      'section4': {
        controller: 'Section4Controller as vm',
        templateUrl: 'templates/section4.tpl.html'
      }
    }
  })
  .state('page2', {
    url: '/page2',
    views: {
      '': {
        templateUrl: 'templates/page2.tpl.html',
      },
      'section1': {
        controller: 'Section1Controller as vm',
        templateUrl: 'templates/section1.tpl.html'
      },
      'section2': {
        controller: 'Section2Controller as vm',
        templateUrl: 'templates/section2.tpl.html'
      },
      'section3': {
        controller: 'Section3Controller as vm',
        templateUrl: 'templates/section3.tpl.html'
      }
    }
  })

Then, when you lay out the views, they look something like this:

<div ui-view="section1"></div>
<div ui-view="section2"></div>
<div ui-view="section3"></div>
<div ui-view="section4"></div>

Upvotes: 2

Related Questions