详细谈谈AngularJS的子级作用域问题


Posted in Javascript onSeptember 05, 2016

前言

AngularJS自带指令目前有ng-includeng-viewng-switchng-repeat。这样的原因是因为,这些指令虽然是AngularJS内部定义的,但是也是和directive实现的方法都是一样的,其内部使用的是scope:true的方式,子作用域继承了父级的作用,并且构建了一个独立的子作用域,所有双向绑定实现不了,只能单独实现子级作用域继承父级的属性。

AngularJS的继承是通过javascript的原型继承方式实现的,进行原型继承即意味着父作用域在子作用域的原型链上。因为原型链的检索只会在属性检索的时候触发,不会在改变属性值的时候触发。所以我们需要把原始类型转换成对象,把值绑定在对象的属性上。

详细谈谈AngularJS的子级作用域问题

大家可以在示例上看到,经过改造之后,就可以实现子级修改父级作用域的属性。原始类型只能继承父类的作用域。

实现方法目前看有三种,下面一次来介绍

通过给父级scope上添加{}来实现,把原始类型转换成对象。

代码如下:

<!DOCTYPE html>
<html lang="en" ng-app="childScope">
<head>
 <meta charset="UTF-8">
 <title></title>
 <script src="lib/angular.min.js" type="text/javascript"></script>
 <style>
 .inputOne{
  width: 100px;
  height: 50px;
  background: skyblue;
 }
 .inner{
  border: 1px solid skyblue;
  width: 200px;
  height: 150px;
 }
 .outer{
  border: 1px solid salmon;
  width: 200px;
  height: 150px;
 }
 .sco{
  background: skyblue;
 }
 </style>
</head>
<body ng-controller="childCon">
 <div class="inner">
 <h3>父级作用域</h3>
 <span>{{vm.private1}}</span>
 <span>{{vm.private2}}</span>
 </div>
 <div class="outer">
 <h3>自己作用域</h3>
 <div class="one" ng-include src="'one.html'"></div>
 <div class="two" ng-include src="'two.html'"></div>
 </div>
</body>
<script>
 var app=angular.module("childScope",['template'])
  .controller("childCon",["$scope", function ($scope) {
  var vm=$scope.vm={};
  vm.private1=12;
  vm.private2=13;
  $scope.test=123;
  }]);
 var template=angular.module("template",[])
  .run(["$templateCache", function ($templateCache) {
  $templateCache.put("one.html","" +
   "<div><input type='text' ng-model='vm.private1'/></div>")
  }])
  .run(["$templateCache", function ($templateCache) {
  $templateCache.put("two.html","" +
   "<div><input type='text' ng-model='vm.private2'/>" +
   "<div class='sco'><span>原始类型</span>{{test}}</div>" +
   "</div>")
  }])
</script>
</html>

通过controller as语法来实现

controller as其实相当于controller的示例对象,原理还是把原始类型转换成对象类型。

<!DOCTYPE html>
<html lang="en" ng-app="childScope">
<head>
 <meta charset="UTF-8">
 <title></title>
 <script src="lib/angular.min.js" type="text/javascript"></script>
 <style>
 .inputOne{
  width: 100px;
  height: 50px;
  background: skyblue;
 }
 .inner{
  border: 1px solid skyblue;
  width: 200px;
  height: 150px;
 }
 .outer{
  border: 1px solid salmon;
  width: 200px;
  height: 150px;
 }
 .sco{
  background: skyblue;
 }
 </style>
</head>
<body ng-controller="childCon as vm">
 <div class="inner">
 <h3>父级作用域</h3>
 <span>{{vm.private1}}</span>
 <span>{{vm.private2}}</span>
 </div>
 <div class="outer">
 <h3>自己作用域</h3>
 <div class="one" ng-include src="'one.html'"></div>
 <div class="two" ng-include src="'two.html'"></div>
 </div>
</body>
<script>
 var app=angular.module("childScope",['template'])
  .controller("childCon",["$scope", function ($scope) {
  this.private1=12;
  this.private2=22;
  $scope.test=123;
  }]);
 var template=angular.module("template",[])
  .run(["$templateCache", function ($templateCache) {
  $templateCache.put("one.html","" +
   "<div><input type='text' ng-model='vm.private1'/></div>")
  }])
  .run(["$templateCache", function ($templateCache) {
  $templateCache.put("two.html","" +
   "<div><input type='text' ng-model='vm.private2'/>" +
   "<div class='sco'><span>原始类型</span>{{test}}</div>" +
   "</div>")
  }])
</script>
</html>

使用$parent.name调用内部方法来实现。

进行原型继承即意味着父作用域在子作用域的原型链上,这是JavaScript的特性。

AngularJS的作用域还存在如下内部定义的关系:

      scope.$parent指向scope的父作用域;

      scope.$$childHead指向scope的第一个子作用域;

      scope.$$childTail指向scope的最后一个子作用域;

      scope.$$nextSibling指向scope的下一个相邻作用域;

      scope.$$prevSibling指向scope的上一个相邻作用域;

通过在子级作用域中使用scope.$parent.name,来获取对父级作用域的双向绑定。

示例如下:

<!DOCTYPE html>
<html lang="en" ng-app="childScope">
<head>
 <meta charset="UTF-8">
 <title></title>
 <script src="lib/angular.min.js" type="text/javascript"></script>
 <style>
 .inputOne{
  width: 100px;
  height: 50px;
  background: skyblue;
 }
 .inner{
  border: 1px solid skyblue;
  width: 200px;
  height: 150px;
 }
 .outer{
  border: 1px solid salmon;
  width: 200px;
  height: 150px;
 }
 .sco{
  background: skyblue;
 }
 </style>
</head>
<body ng-controller="childCon">
 <div class="inner">
 <h3>父级作用域</h3>
 <span>{{private1}}</span>
 <span>{{private2}}</span>
 </div>
 <div class="outer">
 <h3>自己作用域</h3>
 <div class="one" ng-include src="'one.html'"></div>
 <div class="two" ng-include src="'two.html'"></div>
 </div>
</body>
<script>
 var app=angular.module("childScope",['template'])
  .controller("childCon",["$scope", function ($scope) {
  $scope.private1=12;
  $scope.private2=22;
  $scope.test=123;
  }]);
 var template=angular.module("template",[])
  .run(["$templateCache", function ($templateCache) {
  $templateCache.put("one.html","" +
   "<div><input type='text' ng-model='$parent.private1'/></div>")
  }])
  .run(["$templateCache", function ($templateCache) {
  $templateCache.put("two.html","" +
   "<div><input type='text' ng-model='$parent.private2'/>" +
   "<div class='sco'><span>原始类型</span>{{test}}</div>" +
   "</div>")
  }])
</script>
</html>

总结

以上就是AngularJS子级作用域问题的全部内容,希望对大家学习和工作能有所帮助。大家如果有什么疑问,欢迎提出来。

Javascript 相关文章推荐
setTimeout的延时为0时多个浏览器的区别
May 23 Javascript
js的.innerHTML = &quot;&quot;IE9下显示有错误的解决方法
Sep 16 Javascript
js输出阴历、阳历、年份、月份、周示例代码
Jan 29 Javascript
js写出遮罩层登陆框和对联广告并自动跟随滚动条滚动
Apr 29 Javascript
jquery判断当前浏览器的实现代码
Nov 07 Javascript
使用bootstrap实现多窗口和拖动效果
Sep 22 Javascript
微信小程序 解决swiper不显示图片的方法
Jan 04 Javascript
Vue过滤器的用法和自定义过滤器使用
Feb 08 Javascript
javascript中json对象json数组json字符串互转及取值方法
Apr 19 Javascript
vue项目中导入swiper插件的方法
Jan 30 Javascript
基于Vue 实现一个中规中矩loading组件
Apr 03 Javascript
vue项目中使用fetch的实现方法
Apr 25 Javascript
Vuejs第七篇之Vuejs过渡动画案例全面解析
Sep 05 #Javascript
JS简单获取客户端IP地址的方法【调用搜狐接口】
Sep 05 #Javascript
JS简单随机数生成方法
Sep 05 #Javascript
使用React实现轮播效果组件示例代码
Sep 05 #Javascript
Bootstrap中的fileinput 多图片上传及编辑功能
Sep 05 #Javascript
Bootstrap的fileinput插件实现多文件上传的方法
Sep 05 #Javascript
jQuery树形插件jquery.simpleTree.js用法分析
Sep 05 #Javascript
You might like
php懒人函数 自动添加数据
2011/06/28 PHP
初品cakephp 入门基础
2012/02/16 PHP
php发送post请求的三种方法
2014/02/11 PHP
THINKPHP内容分页代码分享
2015/01/14 PHP
php检测文本的编码
2015/07/26 PHP
基于jQuery的左右滚动实现代码
2010/12/03 Javascript
在页面加载完成后通过jquery给多个span赋值
2014/05/21 Javascript
Js获取图片原始宽高的实现代码
2016/05/17 Javascript
javascript深拷贝的原理与实现方法分析
2017/04/10 Javascript
实例分析JS与Node.js中的事件循环
2017/12/12 Javascript
layui 表单标签的校验方法
2019/09/04 Javascript
JS实现盒子拖拽效果
2020/02/06 Javascript
JavaScript创建表格的方法
2020/04/13 Javascript
vue项目实现设置根据路由高亮对应的菜单项操作
2020/08/06 Javascript
[35:43]2018DOTA2亚洲邀请赛 4.1 小组赛B组 paiN vs Effect
2018/04/03 DOTA
python使用reportlab实现图片转换成pdf的方法
2015/05/22 Python
详解Python编程中基本的数学计算使用
2016/02/04 Python
对python生成业务报表的实例详解
2019/02/03 Python
Django 重写用户模型的实现
2019/07/29 Python
Django自定义模板过滤器和标签的实现方法
2019/08/21 Python
python如何求数组连续最大和的示例代码
2020/02/04 Python
浅谈ROC曲线的最佳阈值如何选取
2020/02/28 Python
HTML5的自定义属性data-*详细介绍和JS操作实例
2014/04/10 HTML / CSS
威盛公司软件C++工程师笔试题面试题
2012/07/16 面试题
Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型
2013/10/30 面试题
硅酸盐工业控制专业应届生求职信
2013/11/02 职场文书
青年文明号复核材料
2014/02/11 职场文书
网吧消防安全责任书
2014/07/29 职场文书
观看禁毒宣传片后的感想
2015/08/11 职场文书
高中生社会实践心得体会
2016/01/14 职场文书
《学会看病》教学反思
2016/02/17 职场文书
《夜莺的歌声》教学反思
2016/02/22 职场文书
2016道德模范先进事迹材料
2016/02/26 职场文书
Python Pandas读取Excel日期数据的异常处理方法
2022/02/28 Python
详解OpenCV曝光融合
2022/04/29 Python
nginx lua 操作 mysql
2022/05/15 Servers