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 相关文章推荐
Javascript结合css实现网页换肤功能
Nov 02 Javascript
原生JS可拖动弹窗效果实例代码
Nov 09 Javascript
浅析JavaScript中的delete运算符
Nov 30 Javascript
javascript如何写热点图
Dec 08 Javascript
js获取所有checkbox的值的简单实例
May 30 Javascript
Javascript如何判断数据类型和数组类型
Jun 22 Javascript
关于JSON与JSONP简单总结
Aug 16 Javascript
玩转NODE.JS(四)-搭建简单的聊天室的代码
Nov 11 Javascript
JavaScript评论点赞功能的实现方法
Mar 13 Javascript
微信小程序实现下载进度条的方法
Dec 08 Javascript
vue slot与传参实例代码讲解
Apr 28 Javascript
jQuery实现判断滚动条滚动到document底部的方法分析
Aug 27 jQuery
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和ACCESS写聊天室(八)
2006/10/09 PHP
使用openssl实现rsa非对称加密算法示例
2014/01/24 PHP
php制作文本式留言板
2015/03/18 PHP
php ajax异步读取rss文档数据
2016/03/29 PHP
Yii2 rbac权限控制之菜单menu实例教程
2016/04/28 PHP
JS option location 页面跳转实现代码
2008/12/27 Javascript
浅析onsubmit校验表单时利用ajax的return false无效问题
2013/07/10 Javascript
一个非常全面的javascript URL解析函数和分段URL解析方法
2014/04/12 Javascript
jQuery获取选中内容及设置元素属性的方法
2014/07/09 Javascript
百度UEditor编辑器如何关闭抓取远程图片功能
2015/03/03 Javascript
vue2.0+webpack环境的构造过程
2016/11/08 Javascript
JavaScript 通过Ajax 动态加载CheckBox复选框
2017/08/31 Javascript
vue配置接口域名方法总结
2019/05/12 Javascript
inquirer.js一个用户与命令行交互的工具详解
2019/05/18 Javascript
express框架下使用session的方法
2019/07/31 Javascript
Angular8 Http拦截器简单使用教程
2019/08/20 Javascript
JS开发自己的类库实例分析
2019/08/28 Javascript
Python实现根据指定端口探测服务器/模块部署的方法
2014/08/25 Python
详解python进行mp3格式判断
2016/12/23 Python
Python数据结构与算法之使用队列解决小猫钓鱼问题
2017/12/14 Python
用python wxpy管理微信公众号并利用微信获取自己的开源数据
2019/07/30 Python
python打开使用的方法
2019/09/30 Python
详解python内置常用高阶函数(列出了5个常用的)
2020/02/21 Python
python 动态绘制爱心的示例
2020/09/27 Python
纯CSS改变webkit内核浏览器的滚动条样式
2014/04/17 HTML / CSS
生产助理岗位职责
2014/06/18 职场文书
奥林匹克运动会口号
2014/06/19 职场文书
关于诚信的活动方案
2014/08/18 职场文书
承诺书模板
2014/08/30 职场文书
师德师风的心得体会
2014/09/02 职场文书
领导干部作风整顿个人剖析材料
2014/10/11 职场文书
机关单位工作失职检讨书
2014/11/20 职场文书
党员活动总结
2015/02/04 职场文书
师范生见习自我总结
2015/06/23 职场文书
python中sys模块的介绍与实例
2021/04/17 Python
golang使用map实现去除重复数组
2022/04/14 Golang