0

I am new to angularJs and I need your help.

I have the following example where I am trying to do an action on an element on the parent page from the inner page but I do not understand why it behaves in a strange way: I can't set a default value or action using the scope but I can do that using the rootScope. At the same time I can't read its value using the rootScope but I can read it using the scope.

Here is my example:

This is the parent page content wrapper:

<div class="page-content-wrapper">
    <div ng-class="settings.layout.pageContent">
        <!-- BEGIN STYLE CUSTOMIZER(optional) -->
        <!-- END STYLE CUSTOMIZER -->
        <!-- BEGIN ACTUAL CONTENT -->
        <div class="page-bar">
            <div ncy-breadcrumb></div>
            <div class="page-toolbar" ng-show="settings.layout.showHeaderTools">
                <div id="date-range" class="pull-right tooltips btn btn-sm" data-container="body" data-placement="bottom" data-original-title="Change dashboard date range">
                    <i class="icon-calendar"></i>&nbsp;
                    <span class="thin uppercase hidden-xs"></span>&nbsp;
                    <i class="fa fa-angle-down"></i>
                </div>
                <div class="actions">
                    <select class="form-control" ng-change="changeSchema();" ng-model="selectedSchema">
                        <option value="A">Schema A</option>
                        <option value="B">Schema B</option>
                        <option value="C">Schema C</option>
                        <option value="D">Schema D</option>
                        <option value="E">Schema E</option>
                    </select>
                </div>
            </div>
        </div>
        <h3 class="page-title hidden-print" data-ng-bind="$state.current.data.pageTitle"></h3>
        <div ui-view class="fade-in-up"> </div>
        <!-- END ACTUAL CONTENT -->
    </div>
</div>

This is the controller of the inner page:

angular.module('MetronicApp').controller('dashboardController', function ($rootScope, $scope, $http, $timeout, NgMap) {
    $scope.$on('$viewContentLoaded', function () {
        // initialize core components
        App.initAjax();
    });

    $scope.data = {};
    // set sidebar closed and body solid layout mode
    $rootScope.settings.layout.pageContentWhite = true;
    $rootScope.settings.layout.pageBodySolid = false;
    $rootScope.settings.layout.pageSidebarClosed = true;
    $rootScope.settings.layout.showHeaderTools = true;
    $rootScope.settings.layout.pageContent = 'page-content bg-grey-steel';
    $scope.isLoading = false;
    $scope.data.selectedKPI = "Profit";


    $rootScope.selectedSchema = "A";
    $rootScope.changeSchema = function () {
        console.log($scope.selectedSchema);
    };
});

In my example, $rootScope.selectedSchema = "A"; set the default value but if I use $scope.selectedSchema = "A"; it does not work and at the same time I can't read the value using $rootScope.selectedSchema and it returns undefined, but I can read it using the $scope.selectedSchema and it returns the selected value.

Any help to understand this behavior?

Setily
  • 814
  • 1
  • 9
  • 21
Mo Haidar
  • 3,748
  • 6
  • 37
  • 76
  • 1
    Possible duplicate of [Difference between $scope and $rootScope](http://stackoverflow.com/questions/22785775/difference-between-scope-and-rootscope) – sabithpocker Sep 22 '16 at 09:15

2 Answers2

2

Everytime you inject $scope to a controller, new instance is created (Check $scope.id). If you want to pass data between controllers, you should make use of service. Check this post on stack overflow.

LINK

Community
  • 1
  • 1
g.005
  • 396
  • 1
  • 12
0

According to your code, since you are using $rootScope.selectedSchema = "A"; selectedSchema is the direct property of the rootscope.

when ever we change the selectedSchema from the select box, and a new selectedSchema property is added to the childScope($scope). This new property hides/shadows the parentScope($rootscope) property with the same name.

So, when you are displaying the select field by assigning $rootScope.selectedSchema = "A"; by default its showing 'A', but if you change it once, a new $scope.selectedSchema will be created and it over-rides the $rootScope.selectedSchema, so you are then able to access using $scope.selectedSchema.

So,inorder to change the rootScope value diretly, you have to take a hash object and point its key to the value.

Eg: $rootScope.data = {}
    $rootScope.data.selectedSchema = 'A'

Here is an example I created illustrating this example.

angular.module('myApp', [])
.run(function($rootScope) {
    
})
.controller('myCtrl', function($scope, $rootScope) {
$rootScope.data = {'selectedSchema': 'A'}
  $scope.changeSchema = function() {
        console.log($scope.data.selectedSchema)
        console.log($rootScope.data.selectedSchema)
    };
    
    $scope.getOrig = function() {
        return $rootScope.data.selectedSchema;
    };
})
.controller('myCtrl2', function($scope, $rootScope) {
$rootScope.selectedSchema = 'A';
    $scope.changeSchema = function() {
        console.log($scope.selectedSchema)
        console.log($rootScope.selectedSchema)
    };
    
       
    $scope.getOrig = function() {
        return $rootScope.selectedSchema;
    };
});
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.min.js"></script>
<div ng-app="myApp">
    
    <div ng-controller="myCtrl">
        <strong>Assiging to an object scope changes rootscope also.</strong>
        <br/>
        <select class="form-control" ng-change="changeSchema();" ng-model="data.selectedSchema">
                        <option value="A">Schema A</option>
                        <option value="B">Schema B</option>
                        <option value="C">Schema C</option>
                        <option value="D">Schema D</option>
                        <option value="E">Schema E</option>
                    </select>
          <br/>
          Rootscope Value: {{getOrig()}}
          <br/>
        
    </div>
      <br/><br/>
      <div ng-controller="myCtrl2">
        <strong>Direct assignmennt.scope will not change rootscope. </strong><br>
         <select class="form-control" ng-change="changeSchema();" ng-model="selectedSchema">
                        <option value="A">Schema A</option>
                        <option value="B">Schema B</option>
                        <option value="C">Schema C</option>
                        <option value="D">Schema D</option>
                        <option value="E">Schema E</option>
                    </select>
          <br/>
          Rootscope Value: {{getOrig()}}
          <br/>
        
      </div>
    </div>

Pls, run and compare both representations.

Here is Js Fiddle.

Sravan
  • 18,467
  • 3
  • 30
  • 54