zoukankan      html  css  js  c++  java
  • 理解angularjs的作用域

    <!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"},
             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"},
        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元素,具体要看你的目标是什么来定了。

  • 相关阅读:
    hdu 1455 N个短木棒 拼成长度相等的几根长木棒 (DFS)
    hdu 1181 以b开头m结尾的咒语 (DFS)
    hdu 1258 从n个数中找和为t的组合 (DFS)
    hdu 4707 仓鼠 记录深度 (BFS)
    LightOJ 1140 How Many Zeroes? (数位DP)
    HDU 3709 Balanced Number (数位DP)
    HDU 3652 B-number (数位DP)
    HDU 5900 QSC and Master (区间DP)
    HDU 5901 Count primes (模板题)
    CodeForces 712C Memory and De-Evolution (贪心+暴力)
  • 原文地址:https://www.cnblogs.com/danghuijian/p/4801262.html
Copyright © 2011-2022 走看看