cdonts
cdonts

Reputation: 9599

How do I reach $rootScope from a component?

I am very new to AngularJS/Ionic/Cordova programming and am trying to handle the visibility of a component using a global variable, so it can be hidden or shown from other components. I am creating the variable when calling the run function, assigning it to $rootScope.

app.run(function($rootScope, $ionicPlatform) {
    $ionicPlatform.ready(function() {
        // Some Ionic/Cordova stuff...

        // My global variable.
        $rootScope.visible = true;
    });
})

My component is:

function MyComponentController($rootScope, $scope) {
    var self = this;
    self.visible = $rootScope.visible;
    alert(self.visible);
}

angular.module('myapp')
    .component('myComponent', {
        templateUrl: 'my-component.template.html',
        controller: MyComponentController
    });

And the template:

<div ng-if="$ctrl.visible">
  <!-- ... -->
</div>

However the alert message always shows "undefined". What am I missing?

Upvotes: 2

Views: 919

Answers (2)

Estus Flask
Estus Flask

Reputation: 222319

$rootScope.visible isn't watched when being assigned as self.visible = $rootScope.visible. And it is undefined at the moment when component controller is instantiated.

It can be

function MyComponentController($rootScope, $scope) {
    var self = this;

    $scope.$watch(function () { return $rootScope.visible }, function (val) { 
        self.visible = val;
    });
}

By the way, it is likely available as $scope.$parent.visible and can be bound in template as ng-if="$parent.visible", but this is antipattern that is strongly discouraged.

There may be better approaches:

  • top-level AppController and <my-component ng-if="visible">, so the component doesn't have to control its own visibility

  • broadcasting it with scope events, $rootScope.$broadcast('visibility:myComponent')

  • using a service as event bus (that's where RxJS may be helpful)

  • using a router to control the visibility of views, possibly with route/state resolver (this is the best way)

Upvotes: 1

tkhm
tkhm

Reputation: 880

How about change self to $scope like this:

function MyComponentController($rootScope, $scope) {
    $scope.visible = $rootScope.visible;
    alert($scope.visible);
}

Upvotes: 0

Related Questions