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 相关文章推荐
DB.ASP 用Javascript写ASP很灵活很好用很easy
Jul 31 Javascript
Jquery实现遮罩层的方法
Jun 08 Javascript
基于jQuery实现的旋转彩圈实例
Jun 26 Javascript
JS实现上下左右对称的九九乘法表
Feb 22 Javascript
Bootstrap布局组件教程之Bootstrap下拉菜单
Jun 12 Javascript
微信小程序实战之运维小项目
Jan 17 Javascript
详解webpack4升级指南以及从webpack3.x迁移
Jun 12 Javascript
详解Vue微信授权登录前后端分离较为优雅的解决方案
Jun 29 Javascript
Vue2实时监听表单变化的示例讲解
Aug 30 Javascript
详解@angular/cli 改变默认启动端口两种方式
Nov 29 Javascript
实现elementUI表单的全局验证的方法步骤
Apr 29 Javascript
vue3获取当前路由地址
Feb 18 Vue.js
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
overlord人气高涨,却被菲利普频繁举报,第四季很难在国内上映
2020/05/06 日漫
php批量上传的实现代码
2013/06/09 PHP
PHP对表单提交特殊字符的过滤和处理方法汇总
2014/02/18 PHP
php获取文章上一页与下一页的方法
2014/12/01 PHP
PHP 绘制网站登录首页图片验证码
2016/04/12 PHP
JavaScript判断变量是否为undefined的两种写法区别
2013/12/04 Javascript
jQuery中slideUp 和 slideDown 的点击事件
2015/02/26 Javascript
jquery+css实现的红色线条横向二级菜单效果
2015/08/22 Javascript
JavaScript的removeChild()函数用法详解
2015/12/27 Javascript
canvas实现图像截取功能
2017/02/06 Javascript
C#微信小程序服务端获取用户解密信息实例代码
2017/03/10 Javascript
浅谈NodeJs之数据库异常处理
2017/10/25 NodeJs
vue富文本编辑器组件vue-quill-edit使用教程
2018/09/21 Javascript
微信小程序MUI侧滑导航菜单示例(Popup弹出式,左侧不动,右侧滑动)
2019/01/23 Javascript
图文详解vue框架安装步骤
2019/02/12 Javascript
JS数组进阶示例【数组的几种函数用法】
2020/01/16 Javascript
详解Webpack抽离第三方类库以及common解决方案
2020/03/30 Javascript
vue 中的动态传参和query传参操作
2020/11/09 Javascript
[01:04:01]2014 DOTA2华西杯精英邀请赛5 24 DK VS VG
2014/05/25 DOTA
Python读取Excel的方法实例分析
2015/07/11 Python
Python实现控制台中的进度条功能代码
2017/12/22 Python
python 利用pandas将arff文件转csv文件的方法
2019/02/12 Python
Django RBAC权限管理设计过程详解
2019/08/06 Python
python如何通过twisted搭建socket服务
2020/02/03 Python
TensorFlow Autodiff自动微分详解
2020/07/06 Python
HearthSong官网:儿童户外玩具、儿童益智玩具
2017/10/16 全球购物
LUISAVIAROMA中国官网:时尚奢侈品牌购物网站
2020/11/01 全球购物
简述安装Slackware Linux系统的过程
2012/01/12 面试题
管理科学大学生求职信
2013/11/13 职场文书
班班通项目实施方案
2014/02/25 职场文书
2014年乡镇植树节活动方案
2014/02/28 职场文书
国际贸易毕业生自荐书
2014/06/22 职场文书
在职党员进社区活动总结
2014/07/05 职场文书
上班离岗检讨书
2014/09/10 职场文书
公司内部升职自荐信
2015/03/27 职场文书
深入浅析Django MTV模式
2021/09/04 Python