AngularJS Modules/Scope Sharing

Chancho picture Chancho · Dec 23, 2013 · Viewed 24k times · Source

I recently started using AngularJS and the way I'm building my apps now is like this:

MainController.js

var app = angular.module('app', ['SomeController', 'MainController']);

app.controller('MainController', function ($scope) {
    // do some stuff
}

SomeController.js

var SomeController= angular.module('SomeController', []);

SomeController.controller('SomeController', function ($scope) {
    $scope.variable = "test";
    // do some otherstuff
}

The problem that Im' running into is that the scope is not being shared between modules. From MainController I can't get the variable "test" for example.

  • What is the best practice for this? Do I store all my controllers in 1 module in 1 file?
  • How can i have 1 page with 2 controllers and share the $scope between them, or is it OK to put everything in just one controller ?

Answer

m59 picture m59 · Dec 23, 2013

You could use a service like this: Live demo here (click).

JavaScript:

var otherApp = angular.module('otherApp', []);
otherApp.factory('myService', function() {
  var myService = {
    someData: ''
  };
  return myService;
});
otherApp.controller('otherCtrl', function($scope, myService) {
  $scope.shared = myService;
});


var app = angular.module('myApp', ['otherApp']);

app.controller('myCtrl', function($scope, myService) {
  $scope.shared = myService; 
});

Markup:

  <div ng-controller="otherCtrl">
    <input ng-model="shared.someData" placeholder="Type here..">
  </div>
  <div ng-controller="myCtrl">
  {{shared.someData}}
  </div>

Here's a nice article on sharing data with services.

You can also nest controllers to have the parent controller's scope properties inherited by the child scope: http://jsbin.com/AgAYIVE/3/edit

  <div ng-controller="ctrl1">
    <span>ctrl1:</span>
    <input ng-model="foo" placeholder="Type here..">
    <div ng-controller="ctrl2">
      <span>ctrl2:</span>
      {{foo}}
    </div>
  </div>

But, the child won't update the parent - only the parent's properties update the child.

You would use "the dot rule" to have updates on the child affect the parent. That means nesting your properties in an object. Since the parent and child both have the same object, changes on that object will be reflected in both places. That's just how object references work. A lot of people consider it best practice to not use inheritance, but put everything in directives with isolated scope.