如果一个元素上有多个指令使用了隔离作用域,其中只有一个可以生效。只有指令模板中的根元素可以获得一个新的作用域。因此,对于这些对象来说scope默认被设置为true。内置指令ng-controller的作用,就是从父级作用域继承并创建一个新的子作用域。它会创建一个新的从父作用域继承而来的子作用域。这里的继承就不在赘述,和面向对象中的继承基本是一直的。
首先我们来分析一段代码:
<div ng-app="app" ng-init="name= '祖父'"> <div ng-init="name='父亲'"> 第一代:{{ name }} <div ng-init="name= '儿子'" ng-controller="SomeController"> 第二代: {{ name }} <div ng-init="name='孙子'"> 第三代: {{ name }} </div> </div> </div> </div>
我们发现第一代,我们初始化name为父亲,但是第二代和第三代其实是一个作用域,那么他们的name其实是一个对象,因此出现的效果如下:
第一代:父亲
第二代: 孙子
第三代: 孙子
我们在修改一下代码,把第三代隔离开来再看看效果:
<div ng-app="app"ng-init="name= '祖父'"> <div ng-init="name='父亲'"> 第一代:{{ name }} <div ng-init="name= '儿子'" ng-controller="SomeController"> 第二代: {{ name }} <div ng-init="name='孙子'" ng-controller="SecondController"> 第三代: {{ name }} </div> </div> </div> </div>
JsCode:
angular.module('app', []) .controller('SomeController',function($scope) { }) .controller('SecondController', function ($scope) { })
效果如下:
第一代:父亲
第二代: 儿子
第三代: 孙子
在修改下代码来看看继承:
<div ng-app="app"ng-init="name= '祖父的吻'"> <div> 第一代:{{ name }} <div ng-controller="SomeController"> 第二代: {{ name }} <div ng-controller="SecondController"> 第三代: {{ name }} </div> </div> </div> </div>
效果如下:
第一代:祖父的吻
第二代: 祖父的吻
第三代: 祖父的吻
如果要创建一个能够从外部原型继承作用域的指令,将scope属性设置为true,简单来说就是可继承的隔离,即不能反向影响父作用域。
再来看个例子:
angular.module('myApp', []) .controller('MainController', function ($scope) { }) .directive('myDirective', function () { return { restrict: 'A', scope:false,//切换为{},true测试 priority: 100, template: '<div>内部:{{ myProperty }}<input ng-model="myProperty"/></div>' }; });
Html代码:
<div ng-controller='MainController' ng-init="myProperty='Hello World!'"> 外部: {{ myProperty}} <input ng-model="myProperty" /> <div my-directive></div> </div>
当我们改变scope的值我们会发现
false:继承但不隔离
true:继承并隔离
{}:隔离且不继承
8、transclude
transclude是一个可选的参数。默认值是false。嵌入通常用来创建可复用的组件,典型的例子是模态对话框或导航栏。我们可以将整个模板,包括其中的指令通过嵌入全部传入一个指令中。指令的内部可以访问外部指令的作用域,并且模板也可以访问外部的作用域对象。为了将作用域传递进去,scope参数的值必须通过{}或true设置成隔离作用域。如果没有设置scope参数,那么指令内部的作用域将被设置为传入模板的作用域。
只有当你希望创建一个可以包含任意内容的指令时,才使用transclude: true。
我们来看两个例子-导航栏: