12

I'd like to share the $scope functions of one controller in another controller, in this case for an AngularUI dialog.

Specifically in the example below, I'd like $scope.scopeVar to be available in PopupCtrl.

Here is a Plunkr

Resolve code based on mlarcher's comment here

main.js

angular.module('MyApp', ['ui.bootstrap']);

var MainCtrl = ['$scope', '$dialog', '$rootScope', function($scope, $dialog, $rootScope) {

  $scope.myTestVar = "hello";

  $scope.myOpts = {
    backdrop: true,
    keyboard: true,
    backdropClick: true,
    resolve: { MainCtrl: function() { return MainCtrl; }},
    templateUrl: 'myPopup.html',
    controller: 'PopupCtrl'
  };

  $scope.scopeVar = 'scope var string that should appear in both index.html and myPopup.html.';
  $rootScope.rootScopeVar = "rootScope var string that should appear in both index.html and myPopup.html.";

  $scope.openDialog = function() {

    var d = $dialog.dialog($scope.myOpts);

    d.open().then(function() {
      $scope.scopeVar = 'scope var string should be changed after closing the popup the first time.';
      $rootScope.rootScopeVar = 'rootScope var string should be changed after closing the popup the first time.';
    });
  };
}];



var PopupCtrl = ['$scope', 'dialog', 'MainCtrl', function ($scope, dialog, MainCtrl) {

   var key;

   for (key in MainCtrl) {
     $scope[key] = MainCtrl[key];
   }

   $scope.close = function(){
     dialog.close();
   }
 }];

index.html

<!DOCTYPE html>
<html ng-app="MyApp">

  <head>
    <script data-require="[email protected]" data-semver="1.1.5" src="http://code.angularjs.org/1.1.5/angular.min.js"></script>
    <script data-require="[email protected]" data-semver="0.3.0" src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.3.0.min.js"></script>
    <script src="script.js"></script>
    <link data-require="bootstrap-css@*" data-semver="2.3.2" rel="stylesheet" href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" />
    <link rel="stylesheet" href="style.css" />
  </head>

  <body ng-controller="MainCtrl">
    <h4>{{scopeVar}}</h4>
    <h4>{{rootScopeVar}}</h4>
    <br>
    <button class="btn btn-primary" type="button" data-ng-click="openDialog()" >Popup</button>
  </body>

</html>

myPopup.html

<div class="modal-body">
   <h4>{{scopeVar}}</h4>
   <h4>{{rootScopeVar}}</h4>
</div>
<div class="modal-footer">
   <button data-ng-click="close()" class="btn btn-large popupLarge" >Close</button>
</div>
0

1 Answer 1

31

You have two choices:

  1. You can have the scope property that should be available across controllers attached to the rootScope instead. So in your case, it will look like:
    $rootScope.scopeVar = "Data that will be available across controllers"; However, using this is not recommended - Read Common Pitfalls

  2. Services. Anytime you have a functionality or data that is to be re-used, you are better off with services.

In your case, you can create a service that stores the data, allows changes to it and passes the data to whoever needs it. This answer describes it in detail.

Sign up to request clarification or add additional context in comments.

2 Comments

Conversely, don't create a service whose only purpose in life is to store and return bits of data, Of course, global state sucks and you should use $rootScope sparingly, like you would (hopefully) use with global variables in any language. In particular, don't use it for code, only data. If you're tempted to put a function on $rootScope, it's almost always better to put it in a service that can be injected where it's needed, and more easily tested.article says [$rootScope exists, but it can be used for evil]docs.angularjs.org/partials/misc/…
I think there's a third option: include the two controllers within a third controller's scope, and then share data using $parent from within each of the child controllers.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.