AngularJS中的作用域实例分析


Posted in Javascript onMay 16, 2018

本文实例讲述了AngularJS中的作用域。分享给大家供大家参考,具体如下:

问题引入

使用 Angular 进行过一段时间的开发后,基本上都会遇到一个这样的坑:

<div ng-controller="TestCtrl">
 <p>{{name}}</p>
 <div ng-if="show">
  <input type="text" ng-model="name">
 </div>
</div>
<script>
function TestCtrl($scope){
  $scope.show = true;
  $scope.name = 'htf';
}
</script>

p 元素和 input 元素绑定同一个变量,你本以为,在输入框输入内容,p 中显示的肯定也是随之变化的。

然而并不是这样,不管 input 中的元素怎么变, p 元素中的都没变化,WTF。

要说这是什么原因,那就要从 Angular 的作用域说起了。

作用域

每个 Angular 应用默认有一个根作用域 $rootScope, 根作用域位于最顶层,从它往下挂着各级作用域。

通常情况下,页面中 ng-model 绑定的变量都是在对应的 Controller 中定义的。如果一个变量未在当前作用域中定义,JavaScript 会通过当前 Controller 的 prototype 向上查找,也就是作用域的继承。

这又分两种情况。

1. 基本类型变量

<div ng-controller="OuterCtrl">
 <p>{{x}}</p>
 <div ng-controller="InnerCtrl">
  <input type="text" ng-model="x">
 </div>
</div>
<script>
function OuterCtrl($scope){
  $scope.x = 'hello';
}
function InnerCtrl($scope){
}
</script>

运行后会发现跟文章开头一样的问题,里面输入框变了,外面的没跟着变。

原因在于,InnerCtrl 中并未定义 x 这个变量,取值的时候,会沿着原型链向上找,找到了 OuterCtrl 中定义的 x ,然后赋值给自己,在 InnerCtrl 的输入框输入值时,改变的是 InnerCtrl 中的 x ,而对 OuterCtrl 中的 x 无影响。此时,两个 x 是独立的。

不过,如果你不嫌麻烦的话,用 $scope.$parent 可以绑定并影响上一层作用域中的基本变量:

<input type="text" ng-model="$parent.x">

2. 引用类型变量

那么,如果上下级作用域想共用变量怎么办呢?

答案是使用引用类型变量。

<div ng-controller="OuterCtrl">
 <p>{{x}}</p>
 <div ng-controller="InnerCtrl">
  <input type="text" ng-model="x">
 </div>
</div>
<script>
function OuterCtrl($scope){
  $scope.data = {};
  $scope.data.x = 'hello';
}
function InnerCtrl($scope){
}
</script>

在这种情况下,两者的 data 是同一个引用,对这个对象上面的属性修改,是可以反映到两级对象上的。

ng-if中的作用域

前面讲的是两级控制器之间的作用域,那跟前面提到的问题有什么关系呢?那个看着不是只有一个 Controller 吗?

其实,并不是只有 Controller 可以创建作用域,ng-if 等指令也会(隐式地)产生新作用域。

总结下来就是,ng-ifng-switchng-include 等会动态创建一块界面的东西,都是自带一级作用域。

因此,在开发过程中,为了避免模板中的变量歧义,应当尽可能使用命名限定,比如 data.x,出现歧义的可能性就比单独的 x 要少得多。

总结

始终将页面中的元素绑定到对象的属性(data.x)而不是 直接绑定到基本变量(x)上。

希望本文所述对大家AngularJS程序设计有所帮助。

Javascript 相关文章推荐
将函数的实际参数转换成数组的方法
Jan 25 Javascript
运算符&amp;&amp;的三个不同层次
Apr 07 Javascript
JS产生随机数的用法小结
Dec 10 Javascript
JavaScript中英文字符长度统计方法示例【按照中文占2个字符】
Jan 17 Javascript
js实现功能比较全面的全选和多选
Mar 02 Javascript
Vue服务端渲染和Vue浏览器端渲染的性能对比(实例PK )
Mar 31 Javascript
jQuery EasyUI window窗口使用实例代码
Dec 25 jQuery
node.js调用C++函数的方法示例
Sep 21 Javascript
KOA+egg.js集成kafka消息队列的示例
Nov 09 Javascript
浅谈layer弹出层按钮颜色修改方法
Sep 11 Javascript
浅谈layer的Icon样式以及一些常用的layer窗口使用方法
Sep 11 Javascript
解决webpack多页面内存溢出的方法示例
Oct 08 Javascript
element-ui 限制日期选择的方法(datepicker)
May 16 #Javascript
npm 更改默认全局路径以及国内镜像的方法
May 16 #Javascript
详解使用create-react-app快速构建React开发环境
May 16 #Javascript
seajs下require书写约定实例分析
May 16 #Javascript
Vue使用高德地图搭建实时公交应用功能(地图 + 附近站点+线路详情 + 输入提示+换乘详情)
May 16 #Javascript
基于Vue2x实现响应式自适应轮播组件插件VueSliderShow功能
May 16 #Javascript
vue input 输入校验字母数字组合且长度小于30的实现代码
May 16 #Javascript
You might like
重置版游戏视频
2020/04/09 魔兽争霸
PL-880隐藏功能
2021/03/01 无线电
PHP实现通用alert函数的方法
2015/03/11 PHP
PHP中$GLOBALS['HTTP_RAW_POST_DATA']和$_POST的区别分析
2017/07/03 PHP
Yii框架通过请求组件处理get,post请求的方法分析
2019/09/03 PHP
js setattribute批量设置css样式
2009/11/26 Javascript
jQuery UI Datepicker length为空或不是对象错误的解决方法
2010/12/19 Javascript
jQuery弹出层始终垂直居中相对于屏幕或当前窗口
2013/04/01 Javascript
jQuery右侧选项卡焦点图片轮播特效代码分享
2015/09/05 Javascript
使用Node.js处理前端代码文件的编码问题
2016/02/16 Javascript
JQuery EasyUI Layout 在from布局自适应窗口大小的实现方法
2016/05/28 Javascript
实现React单页应用的方法详解
2016/08/02 Javascript
深入浅析JS Function()构造函数
2016/08/22 Javascript
微信小程序 HTTPS报错整理常见问题及解决方案
2016/12/14 Javascript
JS实现旋转木马式图片轮播效果
2017/01/18 Javascript
利用n 升级工具升级Node.js版本及在mac环境下的坑
2017/02/15 Javascript
angular过滤器实现排序功能
2017/06/27 Javascript
JavaScript实现树的遍历算法示例【广度优先与深度优先】
2017/10/26 Javascript
利用Node.js检测端口是否被占用的方法
2017/12/07 Javascript
vuejs中监听窗口关闭和窗口刷新事件的方法
2018/09/21 Javascript
vue发送ajax请求详解
2018/10/09 Javascript
Vue2.0+Vux搭建一个完整的移动webApp项目的示例
2019/03/19 Javascript
[48:38]DOTA2亚洲邀请赛 3.31 小组赛 B组 Mineski vs Secret
2018/03/31 DOTA
[01:50:49]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Aster BO3 第三场 1月24日
2021/03/11 DOTA
浅谈MySQL中的触发器
2015/05/05 Python
python使用in操作符时元组和数组的区别分析
2015/05/19 Python
python简单实现计算过期时间的方法
2015/06/09 Python
Python中定时任务框架APScheduler的快速入门指南
2017/07/06 Python
Pycharm debug调试时带参数过程解析
2020/02/03 Python
TensorFlow通过文件名/文件夹名获取标签,并加入队列的实现
2020/02/17 Python
PyQt5中向单元格添加控件的方法示例
2020/03/24 Python
移动端解决悬浮层(悬浮header、footer)会遮挡住内容的3种方法
2015/03/27 HTML / CSS
加入学生会演讲稿
2014/04/24 职场文书
开展批评与自我批评发言材料
2014/05/15 职场文书
早读课迟到检讨书
2014/09/25 职场文书
与死神共舞观后感
2015/06/15 职场文书