AngularJS Scope(作用域)

在 AngularJS 中,作用域(Scope) 是一个非常重要的概念,它指的是 AngularJS 控制器与视图之间的桥梁。$scope 对象是 AngularJS 用于存储模型数据的地方,也是控制器和视图交互的核心。通过 $scope,你可以实现控制器内部的数据和视图的绑定,确保数据的动态更新。

作用域的基本概念

  • 作用域(Scope):是一个对象,它包含了控制器内的数据和函数。AngularJS 的作用域主要由 $scope 对象来实现。
  • 作用域链:AngularJS 会根据控制器层次结构来形成作用域链。父作用域的数据可以在子作用域中访问,但子作用域的数据不会反向传递到父作用域。
  • 作用域的生命周期:作用域的生命周期通常与其所在的控制器的生命周期绑定。例如,当控制器被销毁时,与之相关的作用域也会被销毁。

$scope 对象

  1. 模型数据存储:你可以通过 $scope 对象来定义控制器中的模型数据,并且这些数据可以通过绑定的方式直接在视图中显示。
  2. 方法绑定:通过 $scope,你也可以把函数绑定到视图中,视图中的事件(如点击、输入等)可以触发这些函数。

$scope 的基本使用

示例 1:使用 $scope 定义模型数据

<!DOCTYPE html>
<html ng-app="myApp">
<head>
    <title>Scope 示例</title>
</head>
<body ng-controller="myController">
    <h1>欢迎 {{ name }}!</h1>

    <input type="text" ng-model="name" placeholder="输入你的名字">
    
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
    <script>
        var app = angular.module('myApp', []);
        app.controller('myController', function($scope) {
            $scope.name = '张三';  // 定义作用域变量 name
        });
    </script>
</body>
</html>

在这个例子中:

  • $scope.name 绑定到视图中的 <h1> 标签,显示名字。
  • 输入框与 ng-model="name" 绑定,用户在输入框中输入内容时,name 的值会自动更新。

示例 2:使用 $scope 定义函数

<!DOCTYPE html>
<html ng-app="myApp">
<head>
    <title>Scope 示例</title>
</head>
<body ng-controller="myController">
    <button ng-click="greet()">点击问候</button>

    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
    <script>
        var app = angular.module('myApp', []);
        app.controller('myController', function($scope) {
            $scope.greet = function() {
                alert('你好,' + $scope.name);
            };
            $scope.name = '李四';
        });
    </script>
</body>
</html>

在这个例子中:

  • $scope.greet 是一个绑定到按钮点击事件的函数,用户点击按钮时,会弹出一个包含名字的问候框。

作用域的类型

在 AngularJS 中,作用域主要有两种类型:

  1. $rootScope
    • $rootScope 是一个应用级的作用域,它在整个应用生命周期内都可用。任何控制器都可以访问 $rootScope 上的属性和方法,它是全局的。
    • 然而,$rootScope 的使用应该小心,因为它的属性和方法会在整个应用中都可用,这可能导致意外的全局变量污染。
    示例var app = angular.module('myApp', []); app.controller('myController', function($scope, $rootScope) { $rootScope.globalMessage = "这是全局信息"; $scope.localMessage = "这是局部信息"; });
  2. 局部作用域(子作用域)
    • 局部作用域是每个控制器或指令的作用域。每个控制器都有自己的作用域,这个作用域只在该控制器内有效。
    • 子作用域可以访问父作用域的属性,但反之则不行。
    示例<div ng-app="myApp" ng-controller="parentController"> <div ng-controller="childController"> <p>父作用域消息:{{ parentMessage }}</p> <p>子作用域消息:{{ childMessage }}</p> </div> </div> <script> var app = angular.module('myApp', []); app.controller('parentController', function($scope) { $scope.parentMessage = '这是父作用域消息'; }); app.controller('childController', function($scope) { $scope.childMessage = '这是子作用域消息'; }); </script> 在这个例子中,childController 可以访问 parentController 的作用域数据(parentMessage),但是 parentController 无法访问 childController 的作用域数据(childMessage)。

作用域生命周期

  • 作用域的生命周期与控制器的生命周期紧密相关。每个作用域在控制器实例化时创建,当控制器销毁时,作用域也会销毁。
  • AngularJS 使用 $destroy 事件来销毁作用域,通常这发生在视图元素从 DOM 中被移除时。

示例:销毁作用域

app.controller('myController', function($scope) {
    $scope.$on('$destroy', function() {
        console.log('作用域被销毁了');
    });
});

作用域继承

AngularJS 中的作用域支持继承。子作用域可以继承父作用域的属性和方法。如果父作用域上有某个属性,子作用域也可以访问该属性,但如果子作用域定义了相同的属性,那么它会覆盖父作用域中的属性。

示例 1:作用域继承

<div ng-app="myApp" ng-controller="parentController">
    <div ng-controller="childController">
        <p>父作用域消息:{{ parentMessage }}</p>
        <p>子作用域消息:{{ childMessage }}</p>
    </div>
</div>

<script>
    var app = angular.module('myApp', []);

    app.controller('parentController', function($scope) {
        $scope.parentMessage = '这是父作用域的消息';
    });

    app.controller('childController', function($scope) {
        $scope.childMessage = '这是子作用域的消息';
    });
</script>

示例 2:子作用域覆盖父作用域属性

<div ng-app="myApp" ng-controller="parentController">
    <div ng-controller="childController">
        <p>父作用域消息:{{ parentMessage }}</p>
        <p>子作用域消息:{{ childMessage }}</p>
    </div>
</div>

<script>
    var app = angular.module('myApp', []);

    app.controller('parentController', function($scope) {
        $scope.parentMessage = '这是父作用域的消息';
    });

    app.controller('childController', function($scope) {
        $scope.childMessage = '这是子作用域的消息';
        $scope.parentMessage = '子作用域覆盖了父作用域的消息';
    });
</script>

总结

  • $scope 是 AngularJS 中用于绑定控制器和视图的对象,它包含了数据和函数,是视图和控制器之间的数据桥梁。
  • $scope 支持双向数据绑定,确保控制器数据和视图保持同步。
  • 作用域有多种类型,包括 $rootScope(全局作用域)和局部作用域(子作用域)。
  • 子作用域可以访问父作用域的数据,但父作用域不能访问子作用域的数据。子作用域还可以覆盖父作用域中的属性。
  • 作用域的生命周期与控制器的生命周期相关,控制器销毁时作用域也会销毁。

通过理解和正确使用 $scope,可以让 AngularJS 应用的结构更加清晰和模块化。