本文转载自: http://www.tuicool.com/articles/63iEref

angular中scope的继承与js的原型继承有密切的联系,首先回顾一下js的继承:

function ParentScope(){
this.aString = "parent string";
this.aNumber = 100;
this.anArray = [10,20,30];
this.anObject = {
'property1': 'parent prop1',
'property2': 'parent prop2'
};
this.aFunction = function(){
return 'parent output';
}
} function ChildScope(){
} ChildScope.prototype = new ParentScope();
ChildScope.prototype.constructor= ParentScope;
var childScope = new ChildScope();

ChildScope继承自ParentScope,关系图如下:

如果我们要在 childScope 上查询一个定义在 parentScope 的属性, JavaScript 会先在 childScope 上查找, 如果没有查到, 那么会顺着原型链去查找. 所以以下判别式均为 true

childScope.aString === 'parent string'
childScope.anArray[1] === 20
childScope.anObject.property1 === 'parent prop1'
childScope.aFunction() === 'parent output'

接下来做如下操作

childScope.aString= 'child string'

原型链将不会被访问, 一个新的 aString 会被加入到 childScope 的属性中去, 新的属性会隐藏 parentScope 中的同名属性:

再这么做:

childScope.anArray[1]= 10;

childScope.anObject.property1= 'child prop1';

原型链被访问了. 因为 anArray , anObject 没有在 childScope 中找到.

新的赋值操作均在 parentScope 上进行. childScope 上没有添加任何新的属性.

但如果我们做如下操作:

childScope.anArray= [100, 555];

childScope.anObject= {name: 'Mark', country: 'USA'}

原型链没有被访问, childScope 会获得两个新的属性, 并且会隐藏 parentScope 上的同名属性.

仔细分析, 第一第三次均是对某个属性直接进行赋值, 原型链并不会被访问, 由于属性并不存在, 所以新的属性将会被添加.

而第二次其实是先访问 , 再赋值,原型链就会被打开。

--------------------------------------------------------------------------------------------------------------------------------------------------

再来看Angular scope的继承

以下指令汇创建新的scope,并且在原型上继承父scope

ng-repeat, ng-switch,ng-view,ng-controller

带有scope: true的指令,带有transclude:true的指令

值得注意的是以下指令不会继承父scope

scope: {}的指令,这会创建一个隔离作用域

scope: false ,这会共享作用域

让我们看几个例子:

ng-include

JS:

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

HTML:

<p>{ myPrimitive }</p>
<p>{ myObject.aNumber }</p> // cannot use double curly brackets in jekyll <script type="text/ng-template" id="/tpl1.html">
<input type="number" ng-model="myPrimitive">
</script>
<div ng-include src="'/tpl1.html'"></div> <script type="text/ng-template" id="/tpl2.html">
<input type="number" ng-model="myObject.aNumber">
</script>
<div ng-include src="'/tpl2.html'"></div>

每一个ng-include都会创建一个子scope, 并在原型上继承父scope

向第一个 input 输入数字, 一个新的属性 myPrimitive 将会被创建, 同时隐藏 父 scope 的 myPrimitive ;

向第二个 input 输入数字, 子 scope 并不会创建一个新的属性, 这时候原型继承发挥了作用

第一种情况很可能不是我们期待的结果, 所以可以显式的调用 $parent 来解决这个问题.

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

向第一个 input 键入数字, 这时候就不会产生新的属性了. $parent 指向了 父scope. 但是 $parent 和 原型上的继承并不一定相等. 稍后我们会看到一个例子.

对于所有的 scope, 无论是共享的( scope: false ), 继承的( scope: true ), 还是孤立的( scope: { ... } ),

Angular 都会建立一个 父-子 的层级关系, 这个层级关系是根据 dom 结构的层级关系决定的, 可以通过 $parent , $$childHead , $$childTail 来访问.

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

ng-switch、ng-view

情况与ng-include一样,不赘述

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

ng-repeat

ng-repeat有一些特殊

$scope.myArrayOfPrimitives = [ 11, 22 ];
$scope.myArrayOfObjects = [{num: 101}, {num: 202}]
<ul><li ng-repeat="num in myArrayOfPrimitives">
<input ng-model="num"></input>
</li>
</ul>
<ul><li ng-repeat="obj in myArrayOfObjects">
<input ng-model="obj.num"></input>
</li>
</ul>

对于每一次迭代, ng-repeat 都会创建一个 子scope, 并在原型上继承 父scope, 但是他还会将 父scope 上的属性赋值到 子scope 上 . 新的属性名就是 ng-repeat="** in parentScope.property"中的 **.

源码中的 ng-repeat 是这样的:

childScope = scope.$new(); // child scope prototypically inherits from parent scope ...
childScope[valueIdent] = value; // creates a new childScope property

如果 ** 是 primitive, 那么一份 copy 会被赋值到新的属性上. 修改 子scope 上的新属性自然不会修改 父 scope 上的属性.

如果 ** 是个 object, 那么一个 reference 会被赋值到新的 子scope 属性上. 修改这个属性, 就是修改 父scope 对应的属性.

ng-controller

ng-controller 也是会创建新的 子scope, 同时原型继承 父scope. 如同 ng-include, ng-switch, ng-view.

但是, 使用 $scope 来共享数据被认为是一种不好的操作. 因为原型链可是会一直向上追溯的.

如果想要共享数据, 最好使用 service

--------------------------------------------------------------------------------------------------------------------------------------

directive

我们来总结以下指令中的 scope:

1.scope: false  指令不会创建新的 scope, 没有继承关系. 与 $parent 共享 $scope

2.scope: true 指令会创建一个 子scope, 并在原型上继承 $parent. 如果在一个 DOM 上有多个指令想要创建新的 scope, 会报错.

3.scope: {...} 指令会创建一个 孤立的scope. 这在创建可重用的组件时是最好的选择. 但是, 即使如此, 指令还是希望读取 $parent 的数据.

transclude

指令创建了一个 “transcluded” 的子scope, 在原型上继承其 父scope. 如果上述例子同时具有 transclude: true . 那么这个 “transcluded” scope, 和 “islolated” scope 是姊妹关系. 他们的 $parent 指向同一个 scope. 且 isolate scope 的 $$nextSibling 就是这个 “transcluded scope”. 下图反应了他们之间的关系:

scope的继承的更多相关文章

  1. 精通AngularJS(三)深入scope,继承结构,事件系统和生命周期

    深入探讨 Scope 作用域 每一个 $scope 都是类 Scope 的一个实例.类 Scope 拥有可以控制 scope 生命周期的方法,提供事件传播的能力,并支持模板渲染. 作用域的层次结构 让 ...

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

    转自:http://www.lovelucy.info/understanding-scopes-in-angularjs.html angularjs 中的scope继承关系 ng-include ...

  3. angularjs中的directive scope配置

    angularjs中的directive scope配置 定义directive其中重要的一环就是定义scope,scope有三种形式: 默认的scope,DOM元素上原有的scope scope: ...

  4. 指令的Link函数和Scope

    指令生成出的模板其实没有太多意义,除非它在特定的scope下编译.默认情况下,指令并不会创建新的子scope.更多的,它使用父scope.也就是说,如果指令存在于一个controller下,它就会使用 ...

  5. 深入理解 AngularJS 的 Scope

    JavaScript 的原型继承就是奇葩. 之前在 V2EX 上看到讨论说,不会 OOP 的 JavaScript 的程序员就是野生程序员.看来我是属于野生的.   一.遇到的问题 问题发生在使用 A ...

  6. 理解AngularJS的作用域Scope

    AngularJS中,子作用域一般都会通过JavaScript原型继承机制继承其父作用域的属性和方法.但有一个例外:在directive中使用scope: { ... },这种方式创建的作用域是一个独 ...

  7. 用AngularJS开发的过程中如何查看Scope内容

    scope的继承就好比JS的原型链继承,深入理解Scope:http://www.lovelucy.info/understanding-scopes-in-angularjs.html 通过查看官网 ...

  8. 深入理解 AngularJS 的 Scope(转)

    一.遇到的问题 问题发生在使用 AngularJS 嵌套 Controller 的时候.因为每个 Controller 都有它对应的 Scope(相当于作用域.控制范围),所以 Controller ...

  9. Angularjs Scope 原型链

    我们知道scope是可以继承的.scope的继承和js原型链是同一个概念. <div ng-controller="parentCtrl"> {{name}} < ...

随机推荐

  1. Xshell配色方案(Solarized Dark)

    将以下内容复制并保存到文件中,文件名以xc为后缀,如:Solarized Dark.xcs [Solarized Dark] text= cyan(bold)=93a1a1 text(bold)= m ...

  2. VS2005 Manifest 配置问题总结

    一.问题 编译某个遗留工程后,运行程序时报错,“由于应用程序的配置不正确,应用程序无法启动.重新安装应用程序可能会解决这个问题.” 查看生成的Manifest文件如下: <?xml versio ...

  3. ChemDraw破解版真的不大好用

    一直以来都有很多的用户朋友在网上找ChemDraw破解版使用,但是现在厂商清理的厉害,还有国家对知识产权的保护越来越严格,破解版ChemDraw越来越难找了.大家与其花那么多的时候找破解版的,不如买个 ...

  4. go反射----4构建

    声明:文章内容取自雨痕老师<Go语言学习笔记> 反射库提供了内置函数make和new的对应操作,其中最有意思的就是MakeFunc.可用它实现通用模板,适应不同数据类型. package ...

  5. PDO drivers no value in Windows

    学习php编程遇到 Uncaught exception 'PDOException' with message 'could not find driver' 或者 Undefined class ...

  6. 微信小程序结构分析

    1.Console页面:控制台信息页两个作用: (1)开发直接输入代码并且进行调试: (2)显示小程序的错误输出: 2.Sources页面:源文件调试信息页,用于显示当前项目的脚本文件. 3.Netw ...

  7. Strange Optimization(扩展欧几里得)

    Strange Optimization Accepted : 67   Submit : 289 Time Limit : 1000 MS   Memory Limit : 65536 KB Str ...

  8. General Decimal Arithmetic 浮点算法

    General Decimal Arithmetic http://speleotrove.com/decimal/ General Decimal Arithmetic [ FAQ | Decima ...

  9. What are DESC and ASC Keywords?

    What are DESC and ASC Keywords? ASC is the short form for ascending DESC is the short form for desce ...

  10. java限流(一): Semaphore

    Before obtaining an item each thread must acquire a permit from the semaphore, guaranteeing that an ...