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 相关文章推荐
使用Jquery Aajx访问WCF服务(GET、POST、PUT、DELETE)
Mar 16 Javascript
AMD异步模块定义介绍和Require.js中使用jQuery及jQuery插件的方法
Jun 06 Javascript
javascript中call和apply的用法示例分析
Apr 02 Javascript
javasript实现密码的隐藏与显示
May 08 Javascript
ionic实现带字的toggle滑动组件
Aug 27 Javascript
Bootstrap页面标题Page Header的实现方法
Mar 22 Javascript
iscroll实现下拉刷新功能
Jul 18 Javascript
JS动态修改网页body的背景色实例代码
Oct 07 Javascript
angularjs实现柱状图动态加载的示例
Dec 11 Javascript
jquery实现左右轮播切换效果
Jan 01 jQuery
基于vue cli重构多页面脚手架过程详解
Jan 23 Javascript
Vue快速实现通用表单验证功能
Dec 05 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
PHP实现采集程序原理和简单示例代码
2007/03/18 PHP
Linux下 php5 MySQL5 Apache2 phpMyAdmin ZendOptimizer安装与配置[图文]
2008/11/18 PHP
PHP基于PDO实现的SQLite操作类【包含增删改查及事务等操作】
2017/06/21 PHP
PHP通过get方法获得form表单数据方法总结
2018/09/12 PHP
Javascript实现的分页函数
2007/02/07 Javascript
jquery随机展示头像代码
2011/12/21 Javascript
jquery实现倒计时代码分享
2014/06/13 Javascript
json字符串之间的相互转换示例代码
2014/08/21 Javascript
jquery.form.js实现将form提交转为ajax方式提交的方法
2015/04/07 Javascript
javascript实现炫酷的拖动分页
2015/05/11 Javascript
JavaScript实现跨浏览器的添加及删除事件绑定函数实例
2015/08/04 Javascript
分享bootstrap学习笔记心得(组件及其属性)
2017/01/11 Javascript
支持移动端原生js轮播图
2017/02/16 Javascript
JS实现中国公民身份证号码有效性验证
2017/02/20 Javascript
ionic2屏幕适配实现适配手机、平板等设备的示例代码
2017/08/11 Javascript
浅谈React 服务器端渲染的使用
2018/05/08 Javascript
Layui给数据表格动态添加一行并跳转到添加行所在页的方法
2018/08/20 Javascript
jQuery实现为动态添加的元素绑定事件实例分析
2018/09/07 jQuery
基于nodejs的雪碧图制作工具的示例代码
2018/11/05 NodeJs
vue cli 3.0通用打包配置代码,不分一二级目录
2020/09/02 Javascript
JS时间戳与日期格式互相转换的简单方法示例
2021/01/30 Javascript
Vue项目打包部署到apache服务器的方法步骤
2021/02/01 Vue.js
[41:21]夜魇凡尔赛茶话会 第三期02:看图识人
2021/03/11 DOTA
Python读取sqlite数据库文件的方法分析
2017/08/07 Python
关于python写入文件自动换行的问题
2018/06/23 Python
python 并发下载器实现方法示例
2019/11/22 Python
tensorflow 利用expand_dims和squeeze扩展和压缩tensor维度方式
2020/02/07 Python
基于python实现把json数据转换成Excel表格
2020/05/07 Python
python 实现PIL模块在图片画线写字
2020/05/16 Python
纽约家具、家居装饰和地毯店:ABC Carpet & Home
2017/06/21 全球购物
Pottery Barn阿联酋:购买家具、家居装饰及更多
2019/12/08 全球购物
20岁生日感言
2014/01/13 职场文书
单位工作证明书格式
2014/10/04 职场文书
2014年大堂经理工作总结
2014/11/21 职场文书
学校财务管理制度
2015/08/04 职场文书
JVM之方法返回地址详解
2022/02/28 Java/Android