详细谈谈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 相关文章推荐
jquery判断浏览器类型的代码
Nov 05 Javascript
js获取控件位置以及不同浏览器中的差别介绍
Aug 08 Javascript
jQuery中prevAll()方法用法实例
Jan 08 Javascript
浅谈js函数中的实例对象、类对象、局部变量(局部函数)
Nov 20 Javascript
详解Node.js:events事件模块
Nov 24 Javascript
原生js实现淘宝购物车功能
Jun 23 Javascript
jQuery用户头像裁剪插件cropbox.js使用详解
Jun 07 jQuery
[原创]jQuery实现合并/追加数组并去除重复项的方法
Apr 11 jQuery
vue仿element实现分页器效果
Sep 13 Javascript
解决vue中使用proxy配置不同端口和ip接口问题
Aug 14 Javascript
Vue v-model组件封装(类似弹窗组件)
Jan 08 Javascript
Nuxt.js 静态资源和打包的操作
Nov 06 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实现域名whois查询的代码(数据源万网、新网)
2010/02/22 PHP
php设计模式之命令模式的应用详解
2013/05/21 PHP
保存到桌面、设为桌面且带图标的PHP代码
2013/11/19 PHP
php计算数组不为空元素个数的方法
2014/01/27 PHP
PHP中substr_count()函数获取子字符串出现次数的方法
2016/01/07 PHP
Yii的Srbac插件用法详解
2016/07/14 PHP
分析PHP中单双引号的误区和双引号小隐患
2016/07/19 PHP
PHP常用的类封装小结【4个工具类】
2019/06/28 PHP
PHP反射基础知识回顾
2020/09/10 PHP
关于scrollLeft,scrollTop的浏览器兼容性测试
2013/03/19 Javascript
js获取 type=radio 值的方法
2014/05/09 Javascript
用jQuery向div中添加Html文本内容的简单实现
2016/07/13 Javascript
基于Vue.js实现简单搜索框
2020/03/26 Javascript
详解Vue 方法与事件处理器
2017/06/20 Javascript
vue中实现methods一个方法调用另外一个方法
2018/02/08 Javascript
angular6.0开发教程之如何安装angular6.0框架
2018/06/29 Javascript
element-ui 上传图片后清空图片显示的实例
2018/09/04 Javascript
vue 使用rules对表单字段进行校验的步骤
2020/12/25 Vue.js
Python实现删除Android工程中的冗余字符串
2015/01/19 Python
Windows下实现Python2和Python3两个版共存的方法
2015/06/12 Python
python简单获取数组元素个数的方法
2015/07/13 Python
在类Unix系统上开始Python3编程入门
2015/08/20 Python
Python脚本实时处理log文件的方法
2016/11/21 Python
详解PyTorch批训练及优化器比较
2018/04/28 Python
Django之模型层多表操作的实现
2019/01/08 Python
pycharm 批量修改变量名称的方法
2019/08/01 Python
Python 可变类型和不可变类型及引用过程解析
2019/09/27 Python
keras多显卡训练方式
2020/06/10 Python
迷你分体式空调:SoGoodToBuy
2018/08/07 全球购物
英国健身仓库:Bodybuilding Warehouse
2019/03/06 全球购物
家具促销活动方案
2014/02/16 职场文书
医院院务公开实施方案
2014/05/03 职场文书
超越自我演讲稿
2014/05/21 职场文书
二手房购房意向书
2015/05/09 职场文书
工作收入证明模板
2015/06/12 职场文书
Nginx 根据URL带的参数转发的实现
2021/04/01 Servers