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>
<span class="thin uppercase hidden-xs"></span>
<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?
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.
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.