Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple controllers for a template using routeProvider

I'm starting to develop my first big project using AngularJS and while I was thinking about the design for the app, I found something that I don't understand.

I was thinking in a single-page app, so I'm using ng-view and routeProvider to route each query to the right template and controller. However, some of my templates are a bit complex and I first thought to use different controllers to manage each one. This is, different sections of the same template would be managed by different controllers. The problem (or at least, what I thought was the problem) is that routeProvider only lets to associate one template to one controller. This made me think that I could not use another controller for a template except the one I specified in routing configuration using routeProvider.

Then I started to figure out how to restructure the future project so I could maintain each different functionality in the same template being managed by a single controller and still let interact controllers between them.

After some headaches, I decided to try and implement my first approach to see how it failed and... What a suprise! It worked perfectly! But, I don't know exactly why.

Let me show you this simple example:

script.js

angular.module('myApp', [
  'ngRoute'
])
  .config(function ($routeProvider, $locationProvider) {
    $routeProvider
      .when('/', {
        templateUrl: 'main',
        controller: 'MainCtrl' 
      });

    $locationProvider.html5Mode(true);
  });

angular.module('myApp')
  .controller('MainCtrl', function ($scope) {
    // whatever...
    });
  });

angular.module('myApp')
  .controller('FirstCtrl', function ($scope) {
      $scope.first = function(){
           alert("First");
      };
    });
  });

angular.module('myApp')
  .controller('SecondCtrl', function ($scope) {
      $scope.second= function(){
           alert("Second");
      };
    });
  });

main.html

<div ng-controller="FirstCtrl">
    <button ng-click="first()">First!</button>
</div>

<div ng-controller="SecondCtrl">
    <button ng-click="second()">Second!</button>
</div>

index.html

<body ng-app="myApp">
    <div ng-view=""></div>
</body>

I thought if you configure the route to associate "main" template to "MainCtrl" controller, that would be the only controller interacting with the template, but it's not.

I first thought the "first" and "second" functions would not be found because "FirstCtrl" and "SecondCtrl" weren't declared in the routes configuration. I thought maybe routeProvider would be "wrapping" (or something like that) the "main" template and the "MainCtrl" controller, and "main" template would not have access to the rest of the controllers.

But that's not correct, the "first" and "second" functions from different controllers works correctly. So, what is the point in specifying a controller for a template in routes configuration? You could just set a template to render for a specified query and that template could use any controller of the module.

Maybe this is not a good design, I don't know.

Could you help me to understand this better?

Thanks!

like image 973
Jorge Avatar asked Dec 11 '25 06:12

Jorge


1 Answers

When using $route provider as you're stating:

.config(function ($routeProvider, $locationProvider) {
$routeProvider
  .when('/', {
    templateUrl: 'main',
    controller: 'MainCtrl' 
  });

$locationProvider.html5Mode(true);  });

You're actually wrapping everything within the './' route with MainCrtl.

Therefore when you inject the Main.html view in <div ng-view=></div> you get the following rendering:

 <body ng-app="myApp">
    <div ng-controller='MainCtrl'>    
       <div ng-controller="FirstCtrl">
       <button ng-click="first()">First!</button>
       </div>

       <div ng-controller="SecondCtrl">
       <button ng-click="second()">Second!</button>
       </div>
    </div>

 </body>
like image 66
Gabriel Balsa Avatar answered Dec 13 '25 21:12

Gabriel Balsa



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!