转自:http://www.lovelucy.info/understanding-scopes-in-angularjs.html

angularjs 中的scope继承关系

ng-include

假设在我们的 controller 中,

$scope.myPrimitive = 50;
$scope.myObject    = {aNumber: 11};

HTML 为:

<script type="text/ng-template" id="/tpl1.html"><input ng-model="myPrimitive">
</script>
<div ng-include src="'/tpl1.html'"></div><script type="text/ng-template" id="/tpl2.html"><input ng-model="myObject.aNumber">
</script>
<div ng-include src="'/tpl2.html'"></div>

每一个 ng-include 会生成一个子 Scope,每个子 Scope 都继承父 Scope。

输入(比如”77″)到第一个 input 文本框,则子 Scope 将获得一个新的 myPrimitive 属性,覆盖掉父 Scope 的同名属性。这可能和你预想的不一样。

输入(比如”99″)到第二个 input 文本框,并不会在子 Scope 创建新的属性,因为 tpl2.html 将 model 绑定到了一个对象属性(an object property),原型继承在这时发挥了作用,ngModel 寻找对象 myObject 并且在它的父 Scope 中找到了。

如果我们不想把 model 从 number 基础类型改为对象,我们可以用 $parent 改写第一个模板:

<input ng-model="$parent.myPrimitive">

输入(比如”22″)到这个文本框也不会创建新属性了。model 被绑定到了父 scope 的属性上(因为 $parent 是子 Scope 指向它的父 Scope 的一个属性)。

对于所有的 scope (原型继承的或者非继承的),Angular 总是会通过 Scope 的 $parent, $$childHead 和 $$childTail 属性记录父-子关系(也就是继承关系),图中为简化而未画出这些属性。

在没有表单元素的情况下,另一种方法是在父 Scope 中定义一个函数来修改基本数据类型。因为有原型继承,子 Scope 确保能够调用这个函数。例如,

// 父 Scope 中
$scope.setMyPrimitive = function(value) {$scope.myPrimitive = value;
}

查看 DEMO。参考 StackOverflow。

ng-switch

ng-switch 的原型继承和 ng-include 一样。所以如果你需要对基本类型数据进行双向绑定,使用 $parent,或者将其改为 object 对象并绑定到对象的属性,防止子 Scope 覆盖父 Scope 的属性。

参考 AngularJS, bind scope of a switch-case?

ng-repeat

ng-repeat 有一点不一样。假设在我们的 controller 里:

$scope.myArrayOfPrimitives = [ 11, 22 ];
$scope.myArrayOfObjects    = [{num: 101}, {num: 202}]

还有 HTML:

<ul><li ng-repeat="num in myArrayOfPrimitives"><input ng-model="num"></li>
<ul>
<ul><li ng-repeat="obj in myArrayOfObjects"><input ng-model="obj.num"></li>
<ul>

对于每一个 Item,ng-repeat 创建新的 Scope,每一个 Scope 都继承父 Scope,但同时 item 的值也被赋给了新 Scope 的新属性(新属性的名字为循环的变量名)。Angular ng-repeat 的源码实际上是这样的:

childScope = scope.$new(); // 子 scope 原型继承父 scope ...
childScope[valueIdent] = value; // 创建新的 childScope 属性

如果 item 是一个基础数据类型(就像 myArrayOfPrimitives),本质上它的值被复制了一份赋给了新的子 scope 属性。改变这个子 scope 属性值(比如用 ng-model,即 num)不会改变父 scope 引用的 array。所以上面第一个 ng-repeat 里每一个子 scope 获得的 num 属性独立于 myArrayOfPrimitives 数组:

这样的 ng-repeat 和你预想中的不一样。在 Angular 1.0.2 及更早的版本,向文本框中输入会改变灰色格子的值,它们只在子 Scope 中可见。Angular 1.0.3+ 以后,输入文本不会再有任何作用了。(参考StackOverflow 上的解释)我们希望的是输入能改变 myArrayOfPrimitives 数组,而不是子 Scope 里的属性。为此我们必须将 model 改为一个关于对象的数组(array of objects)。

所以如果 item 是一个对象,则对于原对象的一个引用(而非拷贝)被赋给了新的子 Scope 属性。改变子 Scope 属性的值(使用 ng-model,即 obj.num)也就改变了父 Scope 所引用的对象。所以上面第二个 ng-repeat 可表示为:

这才是我们想要的。输入到文本框即会改变灰色格子的值,该值在父 Scope 和子 Scope 均可见。

总结

一共有四种 Scope:

  1. 普通进行原型继承的 Scope —— ng-include, ng-switch, ng-controller, directive with scope: true
  2. 普通原型继承的 Scope 但拷贝赋值 —— ng-repeat。 每个 ng-repeat 的循环都创建新的子 Scope,并且子 Scope 总是获得新的属性。
  3. 独立的 isolate scope —— directive with scope: {...}。它不是原型继承,但 ‘=’, ‘@’ 和 ‘&’ 提供了访问父 Scope 属性的机制。
  4. transcluded scope —— directive with transclude: true。它也遵循原型继承,但它同时是任何 isolate scope 的兄弟。

对于所有的 Scope,Angular 总是会通过 Scope 的 $parent, $$childHead 和 $$childTail 属性记录父-子关系。

转载于:https://www.cnblogs.com/bonelee/p/6090693.html

angularjs 中的scope继承关系——(2)相关推荐

  1. angularjs 中的scope继承关系——(1)

    转自:http://www.lovelucy.info/understanding-scopes-in-angularjs.html JavaScript 的原型链继承 假设父类 parentScop ...

  2. angularjs中的$scope和$rootScope

    (1)每个控制器的实例都对应一个作用范围对象,即$scope (2)在控制器中声明的Model数据,必须保存在一个作用范围内 (3)一个HTML中可以声明多个控制器实例,每个控制器都有自己的作用范围, ...

  3. python中的序列类型数据结构元素的切片操作_PythonI/O进阶学习笔记_4.自定义序列类(序列基类继承关系/可切片对象/推导式)...

    前言: 本文代码基于python3 Content: 1.python中的序列类分类 2. python序列中abc基类继承关系 3. 由list的extend等方法来看序列类的一些特定方法 4. l ...

  4. 类与类之间的关系:依赖关系和关联关系及继承关系中self是什么? 类里面的特殊成员...

    类与类之间的关系 ⼤千世界, 万物之间皆有规则和规律. 我们的类和对象是对⼤千世界中的所有事物进行归 类. 那事物之间存在着相对应的关系. 类与类之间也同样如此. 在⾯向对象的世界中. 类与类 中存在 ...

  5. Angularjs中的IGGird创建和使用

    AngularJs Ignite 中的Iggrid 官网:http://www.igniteui.com/grid/angular Angularjs的Iggrid使用有两种方式,第一种为iggrid ...

  6. Java面试题 20在面向对象编程里,经常使用is-a来说明对象之间的继承关系

    Java面试题 20在面向对象编程里,经常使用is-a来说明对象之间的继承关系,下列对象中不具备继承关系的是?() A:手机与小米手机 B:企业家与雷军 C:编程语言与Java D:中国与北京 类之间 ...

  7. linux 变量的继承,solaris移植到linux的大坑:bash和sh中环境变量继承的差异

    问题的引出 项目中脚本A .B,A调用B, 其中A中所有命令均使用绝对路径,B中直接使用 在solaris上工作正常,移植到linux中报错: /syscom/lm/linux//backupgen: ...

  8. android studio 继承关系 快捷键,Android Studio快捷键

    快捷键,加粗的是经常会使用的描述 Ctrl+E打开最近操作的文件 Ctrl+Z撤销 Ctrl+Shift+Z重做(在Eclipse中使用的是Ctrl+Y) Ctr+Y删除该行(Eclipse中的删除该 ...

  9. Hibernate中的Entity类之间的继承关系之一MappedSuperclass

    在hibernate中,Entity类可以继承Entity类或非Entity类.但是,关系数据库表之间不存在继承的关系.那么在Entity类之间的继承关系,在数据库表中如何表示呢? Hibernate ...

最新文章

  1. 来自前端开发者的灵魂发问:TensorFlow.js 好学吗?
  2. 转:Silverlight样式写法
  3. python php linux-怎么在linux上运行python
  4. 计算机专业英语教程2.1.1,计算机专业英语教程目录
  5. mpls工作原理通俗解释_用这两种方法向最终用户解释NLP模型的工作原理还是不错的...
  6. 最简单 - 单例模式
  7. AI算法连载11:统计之集成学习
  8. android 自定义组合键,自定义快捷操作 安卓虚拟Home键设置技巧
  9. CentOS下openssh版本降级
  10. 前端开发必要的9个开源框架
  11. 设置TOMCAT TITLE 、 内存大小 、jdk路径
  12. 挪威养老基金给我们的启示
  13. rgss3a解包器_Rgss3a解包器下载
  14. 富士通Fujitsu DPK1786T 打印机驱动
  15. Markdown编辑器使用教程_被迫流浪者的博客
  16. 课堂派“互动课件”文件下载
  17. 怎么关闭服务器管理器自动启动,用 systemctl 管理服务:查看状态、启动/停止服务、开启/取消开机自启动...
  18. 阿里达摩院数学竞赛新一轮考题曝光,李永乐老师曾给出第一题详细解答
  19. From Seeing to Moving: A Survey on Learning for Visual Indoor Navigation (VIL)
  20. 嵌入式分享合集109

热门文章

  1. 一. 视频信息与压缩编码
  2. 大数据SQL日常学习——NVL函数
  3. oracle的后缀名,oracle表空间名字的后缀 :.ora和.dbf有什么不同?
  4. mysql创建用户并授登录权限_mysql创建用户并授予权限
  5. windows进程管理器_软件进程自动重启一遍又一遍……你需要这款自动杀进程的小公举ProcessKO...
  6. JAVA接口返回面积_java – 将接口的返回值限制为实现类的范围
  7. Java项目实训报告
  8. 这些知识点你会吗?redis的分布式布隆过滤器含答案解析
  9. 【Network Security!】搭建文件分享服务器,其实也可以很简单-HFS
  10. java chunked 解码_模拟http请求 带 chunked解析办法一