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="angular.js@1.1.5" data-semver="1.1.5" src="http://code.angularjs.org/1.1.5/angular.min.js"></script>
    <script data-require="ui-bootstrap@0.3.0" 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>
Prahalad Gaggar
  • 11,389
  • 16
  • 53
  • 71
ozandlb
  • 1,024
  • 2
  • 10
  • 23

1 Answers1

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.

Community
  • 1
  • 1
callmekatootie
  • 10,989
  • 15
  • 69
  • 104
  • 1
    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]https://docs.angularjs.org/partials/misc/faq.html#drootscopeexistsbutitcanbeusedforevil – Buddhi Sep 07 '14 at 15:19
  • 4
    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. – ftexperts Dec 09 '14 at 18:08