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

  • 相关阅读:
    hiho_1081_最短路径1
    hiho_1079_离散化
    hiho_1078_线段树区间修改
    hiho_1069_最近公共祖先3
    【.netcore学习】.netcore添加到 supervisor 守护进程自启动报错
    【.NetCore学习】ubuntu16.04 搭建.net core mvc api 运行环境
    【.NetCore学习】ASP.NET Core EF Core2.0 DB First现有数据库自动生成实体Context
    【vue基础学习】vue.js开发环境搭建
    【vue学习】vue中怎么引用laydate.js日期插件
    【年终总结】个人的2017年年终总结
  • 原文地址:https://www.cnblogs.com/danghuijian/p/4801262.html
Copyright © 2011-2022 走看看