详细谈谈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 相关文章推荐
利用js实现前台动态添加文本框,后台获取文本框内容(示例代码)
Nov 25 Javascript
javascript文件中引用依赖的js文件的方法
Mar 17 Javascript
JS实现的一个简单的Autocomplete自动完成例子
Apr 16 Javascript
浅谈jQuery中 wrap() wrapAll() 与 wrapInner()的差异
Nov 12 Javascript
JS仿淘宝实现的简单滑动门效果代码
Oct 14 Javascript
JS实现table表格数据排序功能(可支持动态数据+分页效果)
May 26 Javascript
基于jQuery实现顶部导航栏功能
Dec 27 Javascript
slideToggle+slideup实现手机端折叠菜单效果
May 25 Javascript
详解ElementUI之表单验证、数据绑定、路由跳转
Jun 21 Javascript
详解JS构造函数中this和return
Sep 16 Javascript
Vue三种常用传值示例(父传子、子传父、非父子)
Jul 24 Javascript
浅谈vue-router路由切换 组件重用挖下的坑
Nov 01 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/12/29 PHP
ThinkPHP视图查询详解
2014/06/30 PHP
laravel利用中间件做防非法登录和权限控制示例
2019/10/21 PHP
自己动手制作jquery插件之自动添加删除行的实现
2011/10/13 Javascript
jQuery 快速结束当前正在执行的动画
2013/11/20 Javascript
jQuery 滑动方法slideDown向下滑动元素
2014/01/16 Javascript
下雪了 javascript实现雪花飞舞
2020/08/02 Javascript
react系列从零开始_简单谈谈react
2017/07/06 Javascript
使用vue实现grid-layout功能实例代码
2018/01/05 Javascript
基于JavaScript实现简单的音频播放功能
2018/01/07 Javascript
jQuery选择器之基本过滤选择器用法实例分析
2019/02/19 jQuery
JavaScript运行机制实例分析
2020/04/11 Javascript
[56:38]DOTA2-DPC中国联赛正赛Aster vs Magma BO3 第一场 3月5日
2021/03/11 DOTA
python中遍历文件的3个方法
2014/09/02 Python
python中利用xml.dom模块解析xml的方法教程
2017/05/24 Python
关于Python 3中print函数的换行详解
2017/08/08 Python
Python语言描述KNN算法与Kd树
2017/12/13 Python
简单实现Python爬取网络图片
2018/04/01 Python
Django框架首页和登录页分离操作示例
2019/05/28 Python
使用Python给头像戴上圣诞帽的图像操作过程解析
2019/09/20 Python
python实现KNN分类算法
2019/10/16 Python
python GUI库图形界面开发之PyQt5访问系统剪切板QClipboard类详细使用方法与实例
2020/02/27 Python
解决pyecharts运行后产生的html文件用浏览器打开空白
2020/03/11 Python
销售所有的狗狗产品:Dog.com
2016/10/13 全球购物
SISLEY希思黎官方旗舰店:享誉全球的奢华植物美容品牌
2018/04/25 全球购物
全球最大的游戏市场:G2A
2018/07/05 全球购物
历史系自荐信范文
2013/12/24 职场文书
美德好少年主要事迹
2014/01/29 职场文书
房屋转让协议书
2014/04/11 职场文书
村道德模范事迹材料
2014/08/28 职场文书
80后婚前协议书范本
2014/10/24 职场文书
2014年秘书工作总结
2014/11/25 职场文书
2014年个人教学工作总结
2014/12/09 职场文书
入伍通知书
2015/04/23 职场文书
Windows下使用Nginx+Tomcat做负载均衡的完整步骤
2021/03/31 Servers
java调用Restful接口的三种方法
2021/08/23 Java/Android