详细谈谈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公告滚动+AJAX后台得到数据
Apr 14 Javascript
使用js 设置url参数
Jul 08 Javascript
将list转换为json失败的原因
Dec 17 Javascript
javascript判断移动端访问设备并解析对应CSS的方法
Feb 05 Javascript
浅析JavaScript作用域链、执行上下文与闭包
Feb 01 Javascript
JavaScript &amp; jQuery完美判断图片是否加载完毕
Jan 08 Javascript
js制作可以延时消失的菜单
Jan 13 Javascript
Vue表单验证插件Vue Validator使用方法详解
Apr 07 Javascript
解决JQuery全选/反选第二次失效的问题
Oct 11 jQuery
ES6中let、const的区别及变量的解构赋值操作方法实例分析
Oct 15 Javascript
vue实现二级导航栏效果
Oct 19 Javascript
原生js实现表格循环滚动
Nov 24 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语言流程控制中的主动与被动
2012/11/05 PHP
使用PHP强制下载PDF文件示例
2014/01/17 PHP
PHP+Mysql+Ajax+JS实现省市区三级联动
2014/05/23 PHP
php中Array2xml类实现数组转化成XML实例
2014/12/08 PHP
详解php语言最牛掰的Laravel框架
2017/11/20 PHP
Centos7 Yum安装PHP7.2流程教程详解
2019/07/02 PHP
phpStorm2020 注册码
2020/09/17 PHP
一端时间轮换的广告
2006/06/26 Javascript
修改发贴的编辑功能
2007/03/07 Javascript
CSS和Javascript简单复习资料
2010/06/29 Javascript
jquery选择器使用详解
2014/04/08 Javascript
让图片跳跃起来  javascript图片轮播特效
2016/02/16 Javascript
使用json来定义函数,在里面可以定义多个函数的实现方法
2016/10/28 Javascript
vue-cli的工程模板与构建工具详解
2018/09/27 Javascript
Vue CLI2升级至Vue CLI3的方法步骤
2019/05/20 Javascript
Vue路由管理器Vue-router的使用方法详解
2020/02/05 Javascript
6种JavaScript继承方式及优缺点(小结)
2020/02/06 Javascript
详解js中的原型,原型对象,原型链
2020/07/16 Javascript
详解vue修改elementUI的分页组件视图没更新问题
2020/11/13 Javascript
[01:05:41]EG vs Optic Supermajor 败者组 BO3 第二场 6.6
2018/06/07 DOTA
python实现从网络下载文件并获得文件大小及类型的方法
2015/04/28 Python
python os.listdir按文件存取时间顺序列出目录的实例
2018/10/21 Python
Python实现的统计文章单词次数功能示例
2019/07/08 Python
python基于plotly实现画饼状图代码实例
2019/12/16 Python
Jupyter 无法下载文件夹如何实现曲线救国
2020/04/22 Python
西班牙太阳镜品牌:Hawkers
2018/03/11 全球购物
德国运动营养和健身网上商店:Myprotein.de
2018/07/18 全球购物
ESDlife健康生活易:身体检查预订、搜寻及比较
2019/05/10 全球购物
自荐信格式
2013/12/01 职场文书
一岗双责责任书
2014/04/15 职场文书
《祁黄羊》教学反思
2016/02/20 职场文书
详解Flask开发技巧之异常处理
2021/06/15 Python
PHP实现两种排课方式
2021/06/26 PHP
DE1103使用报告
2022/04/05 无线电
方法汇总:Python 安装第三方库常用
2022/04/26 Python
SQL Server2019安装的详细步骤实战记录(亲测可用)
2022/06/10 SQL Server