<!doctype html>
<html ng-app="myApp">
<head>
<script src="http://angularjs-doc.qiniudn.com/angular.min.js"></script>
<script src="http://angularjs-doc.qiniudn.com/angular.js"></script>
</head>
<body>
<div ng-controller ="mainController" >
Outside myDirective: {{ myProperty }}
<div my-directive ng-init="myProperty = 'wow, this is cool'"> <div>
</div>
<script>
angular.module('myApp', [])
.controller("mainController",function (){})
.directive('myDirective', function() {
return {
restrict: 'A',
scope: false,
template:'<div> Inside myDirective: {{ myProperty }} </div>'
};
})
</script> </body>
</html>
<!doctype html>
<html ng-app="myApp">
<head>
<script src="http://angularjs-doc.qiniudn.com/angular.min.js"></script>
<script src="http://angularjs-doc.qiniudn.com/angular.js"></script>
</head>
<body>
<div ng-controller ="mainController" e ng-init="ccc = 'wow, this is cool'">
Outside myDirective: {{ myProperty }}
aaa Outside myDirective: {{ myProperty }}
<div my-directive ng-init="myProperty = 'wow, this is cool'" b-a="ccc" >
</div>
aaa Outside myDirective: {{ myProperty }}
</div>
<script>
angular.module('myApp', [])
.controller("mainController",function (){})
.directive('myDirective', function() {
return {
restrict: 'EA',
//scope: {b:"=bA"},
scope: {},
template:'<div>aaaa Inside myDirective:{{ myProperty }} {{b}}</div>'
};
})
</script> </body>
</html>

http://www.angularjs.cn/A09C

AngularJS.directive系列:嵌套directive的通讯及scope研究

一、directive中的scope

  directive无疑是AngularJS中比较复杂难懂的部分,而directive中个scope更是其中最复杂的部分了,尤其是在嵌套directive中互相通讯的时候。

  单独的directive中,scope概念还是比较简单的,此时scope的三种取值情况为:

  • scope:false  此时,directive没有独立的scope对象,link函数中引用的scope对象来自于当前节点的默认controller
  • scope:true  此时,directive拥有独立的scope对象,此scope是由父scope对象继承而来,可以访问父scope中的所有属性,此时实际上是通过继承链接(prototype链)访问的父scope中的属性,要注意的是,当给此scope继承而来的属性名称赋值的时候,子scope中会相应建立一个本地属性,此时改变的是本scope的变量属性,父scope中的属性是不会改变的。
  • scope:{propertyName:"=@propertyValue"} 此时,directive中拥有一隔离的scope对象,其实就是一个全新的scope对象,和上面取值为true时的区别就是不能访问父scope中的属性,当然还是可以通过$parent属性去访问父scope对象中属性的。

  当情况改变到嵌套directive中的子(或者说内部)directive中时,内部的directive的scope和我们的理解或习惯性的的认知有所不同,而造成这一切的原因是,AngularJS中其实根本没有嵌套directive一说!只要我们脑子里还把内部的directive当成独立的directive来看待就会明白了。比如我们要实现如下的嵌套directive:

<div my-grid height="500" width="300">
<div my-grid-row height="300">
<div my-grid-cell width=".33">
</div>
<div my-grid-cell width=".34">
</div>
<div my-grid-cell width=".33">
</div>
</div>
<div my-grid-row height="200">
<div my-grid-cell width=".5">
</div>
<div my-grid-cell width=".5">
</div>
</div>
</div>
var $myd=angular.module("myDirectives",[]);
$myd.directive("myGrid",function(){
return{
restrict:"A",
scope:{height:"@height",width:"@width"},
link:function(scope,el,attrs){
}
};
});
$myd.directive("myGridRow",function(){
return{
restrict:"A",
scope:true,
link:function(scope,el,attrs){
}
};
});
$myd.directive("myGridCell",function(){
return{
restrict:"A",
scope:true,
link:function(scope,el,attrs){
}
};
});

  开上面代码可知myGrid设置了隔离的scope,myGridRow和myGridCell申请了继承的独立scope,现在猜猜,myGridRow和myGridCell的scope.$parent是谁,是不是myGrid的scope?不知道又没有tx认为(注意下面是示意代码,不是真的如此引用myGridCell和myGridRow的scope)

myGridCell.scope.$parent=myGridRow.scope  

myGridRow.scope.$parent =myGrid.scope

  如果你也和我以前一样这样认为,那么就大错特错了,实际上应该是这样的:

myGridCell.scope.$parent=myGridRow.scope.$parent=myGrid.scope.$parent

  也就是说,这三级的directive的scope的父scope对象是一个人,也就是myGrid所在div元素的父元素或祖先元素节点上指定的ngController或者通过路由设置给出的controller。

  如果myGridRow和myGridCell的scope设为false或是不设置呢,此时myGrid有独立scope而myGridRow和myGridCell都没有,因此分享myGrid父元素的controller的scope,也就是:

myGrid.scope.$parent=myGridRow.scope=myGridCell.scope

  而如果myGridCell和myGridRow的scope也设置为隔离的scope({}),那么此时和第一种情况一样,三个directive的父scope对象也都是同一个对象:myGrid父元素的controller的scope。

二、嵌套directive的通讯

  以上研究了嵌套directive下的scope,可以看到我们不可能通过访问父或子directive中scope方式进行通讯,那么我们究竟应该怎样在各级directive中通讯呢?我知道的有两种方式:

  1,通过注入$rootScope,然后在$rootScope中调用$broadcast和$on,发送和响应事件,这显然不是好的设计。

  2,通过注入父directive的controller。我们看文档知道,directive有一个require属性,这里明确说明require的是指定的directive的controller,此时link函数可以有第四个参数,就是这个controller。下面看示意代码。

var $myd=angular.module("myDirectives",[]);
$myd.directive("myGrid",function(){
return{
restrict:"A",
scope:{height:"@height",width:"@width"},
    controller:function($scope){
        $scope.getHeight=function(){
          return $scope.height;
        };
        $scope.getWidth=function(){
          return $scope.width;
        };
      },
link:function(scope,el,attrs){
       scope.height=parseInt(scope.height);
        $scope.width=parseInt(scope.width);
}
};
});
$myd.directive("myGridRow",function(){
return{
restrict:"A",
scope:true,
     require:"^myGrid",
     controller:function($scope){
        $scope.getWidth=function(){
          return $scope.pCtrl.getWidth();
        }
      },
link:function(scope,el,attrs,pCtrl){
        scope.pCtrl = pCtrl;
        scope.pHeight = pCtrl.getHeight();
        scope.height=parseInt(attrs["height"]);
}
};
});
$myd.directive("myGridCell",function(){
return{
restrict:"A",
scope:true,
     require:"^myGridRow",
link:function(scope,el,attrs,rowCtrl){
        scope.widthRatio = parseFloat(attr["width"]);
        scope.width=scope.widthRatio * rowCtrol.
}
};
});

  由上面代码可见,父子directive通讯需要的两个要素:

  • 父directive中声明controller函数,这和我们平时声明controller差不多,同样可以注入$scope,不同的是这里还可以注入$element,$attrs等,详细的请相关查阅资料。
  • 子directive中添加require属性,内容就是父directive的名字,前面添加"^"是告诉AngularJS到上级的元素中查找父directive的controller,而不是在同元素中找。如果子directive可以脱离父directive单独用,还需要加上"?",以来通知AngularJS,不是必须的,此时link的第四参数有可能为空。

  注意:上述代码只是示意代码,并不能真正工作,如果你使用上述代码将会发现link函数中并不能获取到真正的数值。这是因为例子中嵌套directive是从内到外的顺序来初始化的,子directive的link函数调用时,AngularJS只是初始化了父Directive对象的Controller对象,父directive的link函数并没有调用过,所以你只能取到空值。我的解决方法时子directive在父directive中注册回调函数,然后由父directive在适当的时候回调子directive的方法,或者注册后就由父directive来布局子directive的html元素,具体要看你的目标是什么来定了。

理解angularjs的作用域的更多相关文章

  1. 理解AngularJS的作用域Scope

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

  2. 理解angularJS中作用域$scope

    angularJS中作用域是什么 作用域(scope)是构成angularJS应用的核心基础,在整个框架中都被广泛使用,因此了解它如何工作是非常重要的 应用的作用域是和应用的数据模型相关联的,同时作用 ...

  3. AngularJS Scope(作用域)

    1. AngularJS Scope(作用域) Scope(作用域) 是应用在 HTML (视图) 和 JavaScript (控制器)之间的纽带. Scope 是一个对象,有可用的方法和属性. Sc ...

  4. 理解AngularJS生命周期:利用ng-repeat动态解析自定义directive

    ng-repeat是AngularJS中一个非常重要和有意思的directive,常见的用法之一是将某种自定义directive和ng-repeat一起使用,循环地来渲染开发者所需要的组件.比如现在有 ...

  5. 转: 理解AngularJS中的依赖注入

    理解AngularJS中的依赖注入 AngularJS中的依赖注入非常的有用,它同时也是我们能够轻松对组件进行测试的关键所在.在本文中我们将会解释AngularJS依赖注入系统是如何运行的. Prov ...

  6. 深入理解AngularJs-scope(一)

    进入正文前的说明:本文中的示例代码并非AngularJs源码,而是来自书籍<<Build Your Own AngularJs>>, 这本书的作者仅依赖jquery和lodas ...

  7. 理解AngularJS中的依赖注入

    点击查看AngularJS系列目录 理解AngularJS中的依赖注入 AngularJS中的依赖注入非常的有用,它同时也是我们能够轻松对组件进行测试的关键所在.在本文中我们将会解释AngularJS ...

  8. AngularJS学习之旅—AngularJS Scope作用域(五)

    1.AngularJS Scope(作用域) Scope(作用域) 是应用在 HTML (视图) 和 JavaScript (控制器)之间的纽带. Scope 是一个对象,有可用的方法和属性. Sco ...

  9. angularJs的作用域和依赖注入

    一.angularJs的作用域 &scope这是局部作用域,先在局部作用域中找,如果没有就在全局作用域中找  &rootScope这是全局作用域 <!DOCTYPE HTML&g ...

随机推荐

  1. 从数学角度看最大期望(EM)算法 II

    [转载请注明出处]http://www.cnblogs.com/mashiqi 2015/3/13 对于隐变量只有有限个取值(比如$N$个)的情况,我们可以将隐变量表示为${z_j} = [{z_{j ...

  2. ionic-native-transitions调用原生页面切换实现ionic路由切换

    废话不多说:ionic-native-transitions调用原生页面切换实现ionic路由切换,从而大大提升ionic应用的性能. ionic-native-transitions是一个ionic ...

  3. Codeforces Round #164 (Div. 2)

    A. Games 模拟. B. Buttons 简单计数. C. Beautiful Sets of Points 显然每行每列只能有一个点,那么最大点数为\(1+min(n, m)\). 在不考虑\ ...

  4. JSBinding+SharpKit / 脚本加密(JSC或Bytecode,参考cocos2d-js)

    现在已经可以编译JSC,目前只能在 Windows 下编译 JSC.这个功能是从 cocos2d-js 抄过来的,他应该也支持在Mac编译,但是我没有试过. 菜单:JSB | Compile all ...

  5. Appium自动化时,如何快速获得Android app的包名和启动页

    在app自动化的时候,经常被问道如何知道app的包名和启动页名称.这个问题很简单: 1. 最直接的方式,去问开发啊,他们告诉你app的包名和启动页. 2. 如果你比较腼腆,又能看到/懂代码,自己把代码 ...

  6. apache-flume-1.5.0-bin windows

    1  testconsole.conf syslog-agent.sources = Syslogsyslog-agent.channels = MemoryChannel-1syslog-agent ...

  7. POI中getLastRowNum() 和getLastCellNum()的区别

    hssfSheet.getLastRowNum();//最后一行行标,比行数小1 hssfSheet.getRow(k).getLastCellNum();//获取列数,比最后一列列标大1

  8. java 进程启用远程查看

    用jconsole 1.启动脚本增加: JAVA_OPTS="-Djava.net.preferIPv4Stack=true -Djava.rmi.server.hostname=192.1 ...

  9. XE6移动开发环境搭建之IOS篇(1):准备安装材料(有图有真相)

    网上能找到的关于Delphi XE系列的移动开发环境的相关文章甚少,本文尽量以详细的图文内容.傻瓜式的表达来告诉你想要的答案. 原创作品,请尊重作者劳动成果,转载请注明出处!!! 1.选择方案 --- ...

  10. ztree

    http://www.s u c h s o.com/projecteactual/ztree-jiaocheng-mvc-checkbox-quanxuan-demo-down.html http: ...