Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access the 'current' scope from a 'root' controller

I have one controller I think of as my 'root' controller, it is the one declared with an ng-controller attribute, then a few other controllers that are instantiated dynamically via a $routeProvider. I want to declare a function that will be available via an ng-click attribute in scope of any of the dynamic/child controllers.

I can declare the function on my root controller, e.g.

$scope.announce = function () {
    alert($scope.specificName);
}

then I see it on all of the scopes for all the 'child' controllers, but the $scope used in this function is local to the root controller, not the currently active scope/controller. How can I access the active, child scope in this function?

like image 397
ProfK Avatar asked Jun 03 '15 07:06

ProfK


1 Answers

I've got something working in this plunker that cover some usecases.

The function will take a parameter. This parameter will have the same name in each scope.

<body ng-app="MyApp">
  <div ng-controller="mainCtrl">
    <button ng-click="announce(specificName)">announce in main</button>
    <div ng-controller="subCtrl">
      <button ng-click="announce(specificName)">announce in sub</button>
    </div>
  </div>
</body>

You main controller look like that :

angular.module('MyApp').controller('mainCtrl', function($scope, ItemService){

    $scope.specificName = "I'm main !";
    $scope.announce = function(specificName){
      alert(specificName);
    }
    
});

And just override the "specificName" var in the sub controller :

angular.module('MyApp').controller('subCtrl', function($scope, ItemService){

    $scope.specificName = "I'm a sub !";
    
});

To call the function in pure JS you can do this in each controller :

$scope.announce($scope.specificName);

EDIT :

I just realized that there is an other solution that could meet your need. You could use a factory or a service to share the function.

How the service could look :

myApp.service("AnnounceService",
    function(){
        var service = {};

        service.announce = function(toAnnounce){
              alert(toAnnounce);
        }

        return service;
    }
);

How your controller will look like :

angular.module('MyApp').controller('subCtrl', function($scope, AnnounceService){

    $scope.announce = AnnounceService.announce;
    $scope.specificName = "I'm a sub !";

    //Equivalent
    $scope.announce($scope.specificName);
    AnnounceService.announce($scope.specificName);
    
});

This is the same thing as you need to declare the specificName in each controller and pass it to the function. But the function will be usable in any part of your application. You just need to inject the service and

Details :

Finally the abstract part in not the function but the name of your var in each controller. A kind of conventional naming.

If this var is state related you can add it in the state definition. (If that's the case i could try to give you an example.)

I also don't recommend at all to give a complete $scope to an other one. That's not a good practice in angular.

Hoping this solved your problem, or give enough clues.

Feel free to ask for more specific thing i'll edit the answer to adapt it to your needs.

like image 78
Okazari Avatar answered Oct 11 '22 13:10

Okazari