angular之中,$state $watch $scope $rootScope 分别是什么?

本文深入探讨了AngularJS的关键概念,包括$scope、$rootScope、$watch及$state的作用与使用方法。介绍了作用域的生命周期、$watch的不同监听模式及其原理,并详细解释了路由服务$state的操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.背景介绍

AngularJs是一个用于设计动态web应用的结构框架,使得开发现代的单一页面应用程序变得更加容易。而且能够简化我们的工作流程, 让我们只专心于业务逻辑和数据的处理。$scope $rootScope $watch 和 $state就是里面的几个方法。

 

2.知识剖析

1、$scope——Scope(作用域) 是应用在 HTML (视图) 和 JavaScript (控制器)之间的纽带。Scope 是一个对象,有可用的方法和属性。 Scope 可应用在视图和控制器上。$scope 的使用贯穿整个 Angular App 应用,它与数据模型相关联,同时也是表达式执行的上下文。 有了 $scope 就在视图和控制器之间建立了一个通道,基于作用域视图在修改数据时会立刻更新 $scope, 同样的 $scope发生改变时也会立刻重新渲染视图。

 2、$rootscope——每一个Angular应用都会有一个 $rootScope。这个 $rootScope 是最顶级的scope,它对应着含有 ng-app 指令属性的那个DOM元素。 如果页面上没有明确设定 $scope ,Angular 就会把数据和函数都绑定到这里。Angular 应用启动并生成视图时,会将根 ng-app 元素与 $rootScope 进行绑定.$rootScope 是所有 $scope 的最上层对象, 可以理解为一个 Angular 应用中得全局作用域对象。

3、$scope 的生命周期有4个阶段:

(1)创建:控制器或者指令创建时, Angular 会使用 $injector 创建一个新的作用域,然后在控制器或指令运行时,将作用域传递进去。

2)链接:Angular 启动后会将所有 $scope 对象附加或者说链接到视图上,所有创建 $scope 对象的函数也会被附加到视图上。 这些作用域将会注册当 Angular 上下文发生变化时需要运行的函数.也就是 $watch 函数, Angular 通过这些函数或者何时开始事件循环。

(3)更新:一旦事件循环开始运行,就会开始执行自己的脏值检测.一旦检测到变化,就会触发 $scope 上指定的回调函数。

(4)销毁:通常来讲如果一个 $scope 在视图中不再需要, 需要对其进行清理。

4、$watch——相信使用过angularjs的同学都知道,ng中有个比较重要的特点,叫做双向绑定,那么这个双向绑定是如何实现的呢? 当我们在对绑定的name属性进行修改的时候,angular内部的$digest循环级会执行一次, 他执行的内容是检查我们的 $scope作用域的内容与上次执行$digest循环的时候是否有变化,若有变化就执行$watch()方法绑定的处理函数。 从而 达到了监听作用域属性的效果。

5、$watch(watchExpression, listener, objectEquality);

watchExpression,需要监控的表达式;

listener,处理函数,函数参数如下 function(newValue,oldValue, scope);

objectEquality,是否深度监听,如果设置为true,它告诉Angular检查所监控的对象中每一个属性的变化. 如果你希望监控数组的个别元素或者对象的属性而不是一个普通的值, 那么你应该使用它。

6、$state——在ajax技术发展普及之后,因为其不会留下历史记录方便浏览器访问和对于seo不友好的特点,一个新技术应运而生: 路由,$state就是路由中的一项服务。

7、$state.go()——$state.go()方法可以产生与a链接一样的效果,可以将此方法绑定给一个button按钮, 然后在按钮的点击事件中执行 $state.go(),就可以跳转到相应的页面。

8、$stateparams——$stateParams是一个对象,包含 url 中每个参数的键/值。$stateParams可以为控制器或者服务提供 url 的各个部分。 注意:$stateParams必须与一个控制器相关,并且$stateParams中的“键/值”也必须事先在那个控制器的url属性中有定义。

 

3.常见问题

watch的深度监听是什么意思呢?有什么优缺点呢?

 

4.解决方案

$watch在对待原始类型和引用类型会有不同的处理方式,这就要首先说一说$watch函数的第三个参数。在前面的例子中, 我们知道,$watch函数有接收两个参数,第一个参数是需要监视的对象,第二个参数是在监视对象发生变化时需要调用的函数, 实际上$watch还有第三个参数,它在默认情况下是false。在默认情况下,即不显式指明第三个参数或者将其指明为false时, 我们进行的监视叫做“引用监视”。引用监视的原词的“reference watch”,它的意思是只要监视的对象引用没有发生变化, 就不算它发生了变化。如果我们将$watch的第三个变量设置为true,那么此时我们进行的监视叫做“全等监视”,原词是“equality watch”。 此时,只要$watch的对象有一点风吹草动,它马上就跳出来 既然全等监视这么好,那么我们为什么不直接用全等监视呢?当然,任何事情都有好的坏的两个方面,全等监视固然是好, 但是它在运行时需要先遍历整个监视对象,然后在每次$digest之前使用angular.copy()将整个对象深拷贝一遍然后在运行之后用angular.equal()将前后的对象进行对比。

 

5.编码实战

 

 

6.扩展思考

ui-sref、$state.go 的区别?

(1)ui-sref 一般使用在 <a>...</a>,

 例如:<a ui-sref="message-list">message</a>。

(2)$state.go('someState')一般使用在 controller里面,

例如:.controller('firstCtrl', function($scope, $state) {

            $state.go('login');

           });

(3)这两者的本质上是一样的,从ui-sref的源码可以看出ui-sref最后调用的还是$state.go()方法。

 

 

7.参考文献

参考一:http://yuankeqiang.lofter.com/post/8de51_1454f93;

参考二:https://blog.youkuaiyun.com/u010451286/article/details/50635839;

参考三:http://angular-tips.com/blog/2013/08/watch-how-the-apply-runs-a-digest/;

参考四:https://www.jb51.net/article/80492.html;

参考五:https://www.cnblogs.com/koleyang/p/4576419.html

 

 

8.更多讨论

问题一:$stateParams如果没有用url接收会怎样?

答:如果没有在url里面接收,会导致再次提取$stateParams中的数据的时候,会找不到该数据;$stateParams对象中根本就没有该属性。

问题二: $watch脏检测原理是什么?

答:scope通过$watch方法向this.

watchers数组中添加watcher对象(包含watchFn,listenerFn,valueEq,last四个属性)。每当$digest循环被触发时,它会遍历

watchers数组,执行watcher中的watchFn,获取当前scope上某属性的值(一个watcher对应scope上一个被监听属性),然后去同watcher中的last(上一次的值)做比较,若两值不相等,就执行listenerFn。

问题三:$rootScope是否可以替代$scope?

答:可以,但是不建议这样用,相当于js中的全局变量,定义过多会导致全局污染。

 

<think>我们正在讨论AngularJS中的$scope概念。根据引用[1],$scopeAngularJS中是一个关键概念,它类似于JavaScript的执行环境,具有树形结构。子$scope可以访问父$scope的属性和方法。根$scope位于ng-app指令上。引用[2]提到,$scopeAngularJS作用域的对象,它连接控制器和视图。在控制器中,我们可以将数据附加到$scope上,然后在视图中使用这些数据。引用[3]展示了一个简单的例子:在控制器中,我们定义了一个$scope.name属性,并在视图中通过ng-model和{{}}绑定到输入框和标题。同时,我们在$scope上定义了一个sayHello方法,当按钮被点击时,会更新$scope.greeting。引用[4]详细说明了$scope的特性:它是一个POJO(普通JavaScript对象),提供了一些工具方法(如$watch和$apply)。$scope是表达式的作用域,并且是树形结构,与DOM结构平行。子$scope会继承父$scope(除非覆盖)。每个Angular应用只有一个根$scope$scope可以传播事件,并且是双向数据绑定的基础。总结$scope的作用:1.作为数据模型:$scope是控制器和视图之间的胶水。控制器将数据附加到$scope,视图可以显示和修改这些数据。2.提供上下文:表达式(如{{name}})在$scope的上下文中执行。3.事件传播:$scope可以向上或向下传播事件(使用$emit,$broadcast)。4.观察模型变化:通过$watch方法可以监听$scope上属性的变化,这是双向数据绑定的基础。现在,我们可以根据以上信息组织回答。</think>### AngularJS中的$scope概念及作用 在AngularJS框架中,**$scope** 是一个核心概念,它充当控制器(Controller)与视图(View)之间的**数据绑定桥梁**和**执行上下文环境**。以下是其核心特性和作用: #### 1. **数据模型载体** $scope是一个POJO(普通JavaScript对象),用于存储视图所需的数据模型。控制器将数据附加到$scope后,视图可通过表达式直接访问: ```html <div ng-controller="MyCtrl"> {{ message }} <!-- 显示$scope.message的值 --> </div> ``` ```javascript app.controller('MyCtrl', function($scope) { $scope.message = "Hello Angular!"; // 数据绑定到视图 }); ``` #### 2. **树形作用域结构** $scope采用**原型继承的树形结构**: - 根作用域:通过`ng-app`指令创建,全局唯一[^4] - 子作用域:由`ng-controller`、`ng-repeat`等指令创建 - 继承机制:子$scope可访问父$scope的属性,但重写属性时不会影响父级[^1] ```mermaid graph TD A[根$scope ng-app] --> B[控制器$scope] B --> C[ng-repeat子$scope] B --> D[ng-if子$scope] ``` #### 3. **双向数据绑定** $scope实现**自动视图更新**: - 当`$scope`属性变化时,视图自动更新 - 当表单元素修改值(如`ng-model`),自动更新`$scope`属性[^3] ```javascript $scope.user = { name: 'John' }; // 视图中<input ng-model="user.name">修改值 // 将自动更新$scope.user.name ``` #### 4. **事件传播系统** $scope提供事件机制: - **向上传播**:`$emit()` 向父级$scope冒泡事件 - **向下广播**:`$broadcast()` 向子级$scope广播事件 ```javascript // 子$scope发送事件 $scope.$emit('userUpdated', data); // 根$scope监听事件 $rootScope.$on('userUpdated', callback); ``` #### 5. **变更检测工具** $scope提供关键方法实现双向绑定: - `$watch()`:监听属性变化 ```javascript $scope.$watch('counter', (newVal) => { console.log('counter变化为:', newVal); }); ``` - `$apply()`:手动触发脏检查(用于异步回调) #### 生命周期阶段[^4] 1. **创建**:指令初始化时 2. **注册监控**:`$watch()`绑定监听器 3. **模型变更**:数据更新时 4. **脏检查**:自动或手动触发`$digest`循环 5. **销毁**:`$destroy()`移除作用域 > **关键点**:$scope的树形结构使AngularJS能高效管理数据流和事件,其原型继承机制既实现数据共享(如全局配置),又支持局部隔离(如循环项独立作用域)[^1][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值