【问题标题】:Why can't I use $rootScope instead of $scope?为什么我不能使用 $rootScope 而不是 $scope?
【发布时间】:2013-09-20 19:54:56
【问题描述】:

HTML 文件是这样的:

   <!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>

我写了一个控制器:

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;
        });
    };
}]);

但它在警报框中显示 url 为:/search?fname=&lname= 但是当我在任何地方都使用 $scope 而不是 $rootScope 时,它​​可以正常工作(警报窗口正确显示 url /search?fname=john&lname=player)。 需要帮助以详细了解 $rootScope。谢谢。

【问题讨论】:

    标签: angularjs controller scope rootscope


    【解决方案1】:

    您可以使用$rootScope 代替$scope,但您的变量将是“全局的”并且所有控制器(如果您有多个控制器)都会看到它。

    但是 angular 的优势会丢失一点。因为所有模型(即ng-model)都将在特定的$scope而不是$rootScope下创建

    为每个控制器定义私有$scope

    所以如果你同时使用两个控制器,你可以定义变量名:

     $scope.data = "AAA";
    

    在其他控制器中:

     $scope.data = "BBB";
    

    它们是不同的,因为它们引用了不同的实例(又名控制器)

    关于您的问题:

    你创建了这些行:

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

    在控制器myCtrl1 下。因此它不会更新您的$rootScope,而是更新指向myCtrl1$scope

    我认为您可以使用ng-change 通知$rootScope 更改。

    添加到 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> 
    

    到控制器:

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

    Fiddle

    【讨论】:

    • 其实我只有两个控制器,我愿意有一个 $rootScope 而不是使用工厂/服务。但我无法使用如上所示的 $rootScope。在使用之前,我是否需要在所有控制器之外对其进行处理?
    • 好的。现在我明白了。非常感谢马克西姆的帮助..! :)
    • 解释不正确。这是由于范围的原型性质。与控制器无关,只是它们会导致创建新的子范围。
    • 那么每个新控制器都会有自己的范围,默认情况下会继承自 $rootScope?
    • @MaximShoustin 看看我从你的jsfiddle.net/qcUm6/1得到的小提琴@
    【解决方案2】:

    欢迎来到原型继承的世界。

    您的myCtrl1 作用域继承自$rootScope,但对该作用域上的字符串、整数和布尔值等属性所做的任何更改都不会影响父作用域属性 ($rootScope)。

    基本上,您可以访问父作用域的属性,但不能更改它们的引用(对于对象类型)。任何更改都会导致在子范围内创建新属性。

    请参阅我的小提琴http://jsfiddle.net/qcUm6/1

    阅读本文,您的所有疑虑都会被清除https://github.com/angular/angular.js/wiki/Understanding-Scopes

    【讨论】:

    • 这是一个很棒的链接。当我开始使用 Angular 时,我希望我知道这一点。本来可以为我节省一些 $parent.$parent.etc 的可怕经历... :)
    • @ErikHonn,对于所有从事 AngularJS 工作的人来说,这是必读的,因为我们经常处理作用域 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-16
    • 1970-01-01
    • 1970-01-01
    • 2020-05-17
    • 1970-01-01
    • 1970-01-01
    • 2013-12-07
    相关资源
    最近更新 更多