$scope $rootScope $watch 和 $state

本文深入探讨AngularJS中的核心概念,包括$scope的作用域机制,$rootScope作为全局作用域的使用,$watch的双向绑定原理及其用法,以及$state在路由管理中的应用。通过实例分析,解答了如何通过$rootScope传递参数,如何取消$watch以优化性能等问题,并提供了相关参考资料和常见问题解答。

这里是修真院前端小课堂,每篇分享文从

八个方面深度解析前端知识/技能,本篇分享的是:

【$scope $rootScope $watch 和 $state】

1.背景介绍
在平时的编码中,我们总会想着有什么方法能够简化我们的工作流程,让我们只专心于业务逻辑和数据的处理,而angularjs就为我们程序员实现了这一点。$scope $rootScope $watch 和 $state就是里面的几个方法,今天着重跟大家讨论一下这几个方法

2.知识剖析
$scope
$scope在angularjs中,你可以把它理解成作用域,每个不同的controller,都具有它不同的作用域,所以controller不同,他们的scope是不同的,那么,如果我们想象js那样,做一个全局变量该怎么办呢?这就要说到rootScope了。

$rootScope
$rootScope是由angularJS加载模块的时候自动创建的,每个模块只会有1个rootScope;

$rootScope就相当于一个全局作用域,所以我们保存在其中的东西是全局性的,在任一controller之中都能够使用scope是html和单个controller之间的桥梁,数据绑定就靠他了。rootscope是各个controller中scope的桥梁。用rootscope定义的值,可以在各个controller中使用。

w a t c h 相 信 使 用 过 a n g u l a r j s 的 同 学 都 知 道 , n g 中 有 个 比 较 重 要 的 特 点 , 叫 做 双 向 绑 定 , 那 么 这 个 双 向 绑 定 是 如 何 实 现 的 呢 ? 当 我 们 在 创 建 出 s c o p e 下 的 一 个 新 属 性 的 时 候 , n g 就 会 主 动 为 我 们 新 属 性 加 上 watch 相信使用过angularjs的同学都知道,ng中有个比较重要的特点,叫做双向绑定,那么这个双向绑定是如何实现的呢?当我们在创建出scope下的一个新属性的时候,ng就会主动为我们新属性加上 watch使angularjsngscopengwatch这个方法,这个方法会监听我们的数据变化,当数据变化之后,就立即把view和scope上数据同步。虽然angular会为每一个ng-model添加一个

watch事件,但我们还可以定义己watch事件,但我们还可以定义自己的watch事件,但我们还可以定义自己的watch事件,但我们还可以定义自己的watch,所以需要了解一下$watch的用法;

$watch(watchExpression, listener, objectEquality);

watchExpression:监听的对象,它可以是一个angular表达式如’name’,或函数如function();注意如果是函数的话,需要加上()不能只写函数名;

listener:当watchExpression变化时会被调用的函数或者表达式,它接收3个参数:newValue(新值), oldValue(旧值), scope(作用域的引用)

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

$state
$state是路由中的一项服务,简单来说就是给路由一个对应的状态,让其根据不同的状态加载不同的页面;

3.常见问题
如何通过$rootscope传参

4.解决方案

var myApp = angular.module(‘myApp’, []);
myApp.controller(“mycontroller”, [‘ s c o p e ′ , ′ scope', ' scope,rootScope’, function($scope, $rootScope) {
$rootScope.arr = ‘this a book’

}])
myApp.controller(“mycontroller1”, [‘ s c o p e ′ , ′ scope', ' scope,rootScope’, function($scope, $rootScope) {
$scope.arr = $rootScope.arr;
}])
5.编码实战
demo1

6.扩展思考
怎么取消$watch,为什么取消?

$watch的性能消耗较大,所以对于已经不需要监视的watch,记得定时取消掉。

7.参考文献

http://yuankeqiang.lofter.com/post/8de51_1454f93


https://blog.youkuaiyun.com/u010451286/article/details/50635839

12
8.更多讨论

Q1: s c o p e 和 scope和 scoperootscope的优先级谁高

A1: s c o p e 的 优 先 级 高 , 系 统 会 先 查 找 scope的优先级高,系统会先查找 scopescope内的,如果能找到相应的值,就不会再往上查找!

Q2:$rootscope定义多个,会被覆盖吗?

A2:会被后面一个覆盖掉,不要随便定义

Q3:$state的使用方法?

A3:

看下面,简单来说就是在HTML里面加上href的路径。然后有一个ng-view用来展示信息的地方。

最后一个是具体的路由当,不同的状态时,显示不同的值。

  • 电脑
  • 打印机
  • .when(’/computers’,{template:‘这是电脑分类页面’}) .when(’/printers’,{template:‘这是打印机页面’})

/** * Created by wupeng5 on 2016/5/9. */ var app = angular.module("app",['ui.router','oc.lazyLoad','tableKillModule','selectModule',"select2Module"]).config(function($stateProvider,$controllerProvider,$compileProvider,$filterProvider,$provide,$urlRouterProvider,$httpProvider){ $urlRouterProvider.otherwise('login'); //引入$stateProvider对象,为动态路由做准备 app.register = { stateProvider:$stateProvider } //$locationProvider.html5Mode(true); $httpProvider.defaults.headers.put['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'; $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'; $httpProvider.defaults.headers.common["Accept"] = 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'; $httpProvider.defaults.headers.post['X-Requested-With'] = 'XMLHttpRequest'; $httpProvider.defaults.transformRequest = [function(data) { /** * The workhorse; converts an object to x-www-form-urlencoded serialization. * @param {Object} obj * @return {String} */ var param = function(obj) { var query = ''; var name, value, fullSubName, subName, subValue, innerObj, i; for (name in obj) { value = obj[name]; if (value instanceof Array) { for (i = 0; i < value.length; ++i) { subValue = value[i]; fullSubName = name + '[' + i + ']'; innerObj = {}; innerObj[fullSubName] = subValue; query += param(innerObj) + '&'; } } else if (value instanceof Object) { for (subName in value) { subValue = value[subName]; fullSubName = name + '[' + subName + ']'; innerObj = {}; innerObj[fullSubName] = subValue; query += param(innerObj) + '&'; } } else if (value !== undefined && value !== null) { query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&'; } } return query.length ? query.substr(0, query.length - 1) : query; }; return angular.isObject(data) && String(data) !== '[object File]' ? param(data) : data; }]; //配合nginx处理本地开发, 服务器调式的问题(接口是跨域的) $httpProvider.interceptors.push(function($q){ return { 'request':function(config){ if(config.url.indexOf('html') == -1){ config.url = "" + config.url; } return config || $q.when(config); } } }); //注销RootScope上面的广播事件 //var deregister = $rootScope.$on("rootEvent", function(event,data) { // //}); // //$scope.$on('$destory', function() { // deregister(); // 退订事件 //}); //注册$onRootScope方法,并在执行完毕后直接销毁, 防止内存溢出 $provide.decorator('$rootScope',['$delegate',function($delegate){ Object.defineProperty($delegate.constructor.prototype,'$onRootScope',{ value:function(name,listener){ var unsubscribe = $delegate.$on(name,listener); this.$on('$destroy',unsubscribe); }, enumerable:false }); return $delegate; }]) //使用,不需要手动去销毁这个事件 //$scope.$onRootScope("key",function(){ // console.log("get key"); //}) //$rootScope.$broadcast("key",{name:1}); }); app.factory('timestampMarker', [function() { return { request: function(config) { config.requestTimestamp = new Date().getTime(); return config; }, response: function(response) { response.config.responseTimestamp = new Date().getTime(); return response; } }; }]); app.config(['$httpProvider', function($httpProvider) { $httpProvider.interceptors.push('timestampMarker'); }]); //$http.get('xxxx').then(function(response) { // var time = response.config.responseTimestamp - response.config.requestTimestamp; // console.log('The request took ' + (time / 1000) + ' seconds.'); //}); //当路由变化的时候触发 app.run(function($rootScope,$templateCache) { $rootScope.isLogin = true; $rootScope.loginStyle = ""; $rootScope.$on('$stateChangeStart', function (event, current, previous) { if(current.name != "login" && $rootScope.currentState != current.name){ // console.log($rootScope.currentState); $rootScope.currentState = current.name; } //清理所有template缓存 if (typeof(current) !== 'undefined'){ $templateCache.removeAll(); } $rootScope.currentName = current.name; if($rootScope.currentName == "login"){ $rootScope.isLogin = false; $rootScope.loginStyle = "login"; $rootScope.col = ""; }else{ $rootScope.isLogin = true; $rootScope.loginStyle = ""; } }); });代码审计一下
最新发布
08-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值