Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modify $rootscope property from different controllers

In my rootscope I have a visible property which controls the visibility of a div

app.run(function ($rootScope) {
    $rootScope.visible = false;
});

Example HTML:

<section ng-controller='oneCtrl'>
    <button ng-click='toggle()'>toggle</button>
    <div ng-show='visible'>
        <button ng-click='toggle()'>&times;</button>
    </div>
</section>

Controller:

var oneCtrl = function($scope){
    $scope.toggle = function () {
        $scope.visible = !$scope.visible;
    };
}

The above section works fine, the element is shown or hide without problems. Now in the same page in a different section I try to change the visible variable to show the div but it doesn't work.

<section ng-controller='otherCtrl'>
    <button ng-click='showDiv()'>show</button>
</section>

Controller:

var otherCtrl = function($scope){
    $scope.showDiv = function () {
        $scope.visible = true;
    };
}
like image 732
olanod Avatar asked Feb 27 '13 19:02

olanod


2 Answers

In AngularJS, $scopes prototypically inherit from their parent scope, all the way up to $rootScope. In JavaScript, primitive types are overwritten when a child changes them. So when you set $scope.visible in one of your controllers, the property on $rootScope was never touched, but rather a new visible property was added to the current scope.

In AngularJS, model values on the scope should always "have a dot", meaning be objects instead of primitives.

However, you can also solve your case by injecting $rootScope:

var otherCtrl = function($scope, $rootScope){
  $scope.showDiv = function () {
    $rootScope.visible = true;
  };
}
like image 121
Josh David Miller Avatar answered Nov 20 '22 19:11

Josh David Miller


How familiar are you with the concept of $scope? It looks to me based on your code that you're maintaining two separate $scope variables called "visible" in two different scopes. Do each of your controllers have their own scopes? This is often the case, in which case you're actually editing different variables both named "visible" when you do a $scope.visible = true in different controllers.

If the visible is truly in the rootscope you can do $rootScope.visible instead of $scope.visible, but this is kind of messy.

One option is to have that "otherCtrl" code section in a directive (you should probably be doing this anyway), and then two-way-bind the directive scope to the parent scope, which you can read up on here. That way both the directive and the page controller are using the same scope object.

In order to better debug your $scope, try the Chrome plugin for Angular, called Batarang. This let's you actually traverse ALL of your scopes and see the Model laid out for you, rather than just hoping you're looking in the right place.

like image 42
James M Avatar answered Nov 20 '22 19:11

James M