Multiple controllers with AngularJS in single page app Multiple controllers with AngularJS in single page app angularjs angularjs

Multiple controllers with AngularJS in single page app


What is the problem? To use multiple controllers, just use multiple ngController directives:

<div class="widget" ng-controller="widgetController">    <p>Stuff here</p></div><div class="menu" ng-controller="menuController">    <p>Other stuff here</p></div>

You will need to have the controllers available in your application module, as usual.

The most basic way to do it could be as simple as declaring the controller functions like this:

function widgetController($scope) {   // stuff here}function menuController($scope) {   // stuff here}


I think you are missing the "single page app" meaning.

That doesn't mean you will physically have one .html, instead you will have one main index.html and several NESTED .html file. So why single page app? Because this way you do not load pages the standard way (i.e. browser call that completely refreshes the full page) but you just load the content part using Angular/Ajax. Since you do not see the flickering between page changes, you have the impression that you didn't move from the page. Thus, you feel like you are staying on a single page.

Now, I'm assuming that you want to have MULTIPLE contents for your SINGLE PAGE app: (e.g.) home, contacts, portfolio and store.Your single page/multiple content app (the angular way) will be organized this way:

  • index.html: contains header, <ng-view> and footer
  • contacts.html:contains the contact form (no header, no footer)
  • portfolio.html:contains the portfolio data (no header no footer)
  • store.html: contains the store, no header no footer.

You are in index, you click on the menu called "contacts" and what happens? Angular replaces the <ng-view> tag with the contacts.html code

How do you achieve that? with ngRoute, as you are doing, you will have something like:

app.config(function($routeProvider, $locationProvider) {                          $routeProvider                                                                       .when('/', {                                                     templateUrl: "templates/index.html",                                                        controller:'MainCtrl',                                        })        .when('/contacts', {                                                     templateUrl: "templates/contacts.html",                                                        controller:'ContactsCtrl',                                        })                                                                         .otherwise({                                  template: 'does not exists'           });      });

This will call the right html passing the right controller to it (please note: do not specify ng-controller directive in contacts.html if you are using routes)

Then, of course, you can declare as many ng-controller directives inside your contacts.html page. Those will be child controllers of ContactCtrl (thus inheriting from it). But for a single route, inside the routeProvider, you can declare a single Controller that will act as the "Father controller of the partial view".

EDITImagine the following templates/contacts.html

<div>    <h3>Contacts</h3>    <p>This is contacts page...</p></div>

the above routeProvider will inject a controller into your containing div. Basically the above html automaticaly becomes:

<div ng-controller="ContactsCtrl">    <h3>Contacts</h3>    <p>This is contacts page...</p></div>

When I say you can have others controllers, means that you can plug controllers to inner DOM elements, as the following:

<div>    <h3>Contacts</h3>    <p ng-controller="anotherCtrl">Hello {{name}}! This is contacts page...         </p></div>

I hope this clarify things a bit.

A


I'm currently in the process of building a single page application. Here is what I have thus far that I believe would be answering your question. I have a base template (base.html) that has a div with the ng-view directive in it. This directive tells angular where to put the new content in. Note that I'm new to angularjs myself so I by no means am saying this is the best way to do it.

app = angular.module('myApp', []);                                                                             app.config(function($routeProvider, $locationProvider) {                          $routeProvider                                                                       .when('/home/', {                                                     templateUrl: "templates/home.html",                                                        controller:'homeController',                                        })                                                                              .when('/about/', {                                                   templateUrl: "templates/about.html",                 controller: 'aboutController',          })         .otherwise({                                  template: 'does not exists'           });      });app.controller('homeController', [                  '$scope',                                  function homeController($scope,) {                $scope.message = 'HOME PAGE';                      }                                                ]);                                                  app.controller('aboutController', [                      '$scope',                                   function aboutController($scope) {                $scope.about = 'WE LOVE CODE';                           }                                                ]); 

base.html

<html><body>    <div id="sideMenu">        <!-- MENU CONTENT -->    </div>    <div id="content" ng-view="">        <!-- Angular view would show here -->    </div><body></html>