Why can't I use $rootScope instead of $scope?

exAres picture exAres · Sep 20, 2013 · Viewed 21.3k times · Source

HTML file is this :

   <!DOCTYPE html>
<html lang="en" ng-app="myApp">

<head>
  <meta charset="utf-8">

  <title>HTTP Request</title>

  <script src="angularjs"></script>
  <script src="appjs"></script>

</head>
<body>
        <div ng-controller="myCtrl1">
            First Name: <input type="text" ng-model="fname" required>
            Last Name: <input type="text" ng-model="lname" required>
            <button ng-click="search()">Send HTTP Request</button>
            <p>Searching for : {{fname}} {{lname}}</p>
            <p>Response Status: </p>
            <p>{{status}}</p>
            <p>Data: {{data}}</p><br>
            <p>Total number of results : {{data.numResults}}</p>
        </div>
</body>
</html>

I have written a controller as :

var myApp = angular.module('myApp', []);

myApp.controller('myCtrl1', ['$rootScope', '$http', function($rootScope, $http) {
    $rootScope.fname = "";
    $rootScope.lname="";
    $rootScope.search = function() {

        var search_url = "/search?fname=" + $rootScope.fname + "&lname=" + $rootScope.lname;
        alert (search_url);
//      alert("/search?fname=" + $scope.fname + "&lname=" + $scope.lname);
        $http({method:'GET', url:search_url})
        .success(function(data, status, headers, config) {
            $rootScope.status = status;
            $rootScope.data = data;
            $rootScope.headers = headers;
            $rootScope.config = config;
        });
    };
}]);

But it shows url in alertbox as : /search?fname=&lname= But when I use $scope everywhere instead of $rootScope, it works fine (alert window shows url properly /search?fname=john&lname=player). Need help to understand $rootScope in details. Thanks.

Answer

Maxim Shoustin picture Maxim Shoustin · Sep 20, 2013

You can use $rootScope instead $scope but your variable will be "global" and all controllers (if you have more then one) will see it.

But advantage of angular will be lost a bit. Because all models (a.e ng-model) will be created under specific $scope but not $rootScope

For each controller define private $scope.

so if you use two controllers in both you can define the variable name:

 $scope.data = "AAA";

and in other controller:

 $scope.data = "BBB";

they are different because refer to different instances (aka controllers)

about your problem:

you created this lines:

 First Name: <input type="text" ng-model="fname" required>
 Last Name: <input type="text" ng-model="lname" required> 

under controller myCtrl1. therefore it will not update your $rootScope but $scope that refers to myCtrl1.

I think you can use ng-change to notify $rootScope about change.

add to HTML:

 First Name: <input type="text" ng-model="fname" ng-change ="onfnameChange(fname)" required>
 Last Name: <input type="text" ng-model="lname" ng-change ="onlnameChange(lname)" required> 

to controller:

...
 $scope.onfnameChange = function(val){
   $rootScope.fname = val;
 };

$scope.onlnameChange = function(val){
  $rootScope.lname = val;
};
...

see Fiddle