anjularjs之directive

directive是DOM元素的一个标记(可以是属性、元素名称、类名和文本内容),告诉angular的compiler给这个元素添加指定的行为,或者改变这个元素及其子元素。

angular提供了很多内置的directive(比如ngBind、ngModel和ngClass)方便我们使用,就像可以创建controller和service一样,我们也可以创建自己的directive。

index.html

<div ng-controller="firstController">
  <div my-customer></div>
</div>
script.js

angular.module('docsSimpleDirective', [])
.controller('firstController', ['$scope', function($scope) {
  $scope.customer = {
    name: 'gpl',
    age: 21
  };
}])
.directive('myCustomer', function() {
  return {
    template: 'Name: {{customer.name}} age: {{customer.age}}'
  };
});
结果:
Name: gpl age: 21

自定义指令属性详解

属性 值类型 说明
restrict string 指令的调用方式,A、C、E、M
priority number 指令执行的优先级
template string 指令使用的模板,可将html页面代码写于此。只能与templateUrl二选其一
templateUrl string 从指定的url地址加载模板。只能与template二选其一
replace boolean 是否用模板替换当前元素。true : 将指令标签替换成temple中定义的内容,页面上不会再有<my-directive>标签;false :则append(追加)在当前元素上,即模板的内容包在<my-directive>标签内部。默认false。
transclude boolean 是否将当前元素的内容转移到模板中
scope boolean /object 指定指令的作用域。false(默认值): 使用父作用域作为自己的作用域(每个引用自定义指令的标签若其中一个标签改变某一变量值,则会影响其他标签的值 )。true: 新建一个作用域,该作用域继承父作用域(两个引用自定义指令的标签之间的变量互不影响)。JavaScript对象:与父作用域隔离,并指定可以从父作用域访问的变量
controller function 定义与其他指令进行交互的接口函数
require string 指定需要依赖的其他指令
link function 以编程的方式操作DOM,包括添加监听器等
compile function 编程的方式修改DOM模板的副本,可以返回链接函数

transclude:
定义是否将当前元素(html页面的自定义指令)的内容转移到模板中。 
模板中要接收当前元素内容的标签需要使用ng-transclude指令。

<body >
    <div ng-app="myApp" ng-controller="myController">
        <!-- 引用自定义指令 -->
        <my-directive>自定义指定令内容</my-directive>

        <!-- 模板代码 -->
        <script type="text/ng-template" id="template.html">
            <div> 模板内容</div>
            <div ng-transclude></div>//模板接收上面自定义指令间的内容
        </script>
    </div>

    <script>
        //创建模块
        var app = angular.module('myApp', []);
        //创建控制器
        app.controller('myController', function($scope) {  });
        //创建自定义指令
        app.directive("myDirective", function() {
            return {
                templateUrl : "template.html",
                 transclude : true//转移到模板中
            };
        });
    </script>
</body>

controller属性用于提供对外的接口,即该自定义指令会被其他自定义指令调用。所谓的接口,就是this后的变量或方法。 
controller可以使用的参数,作用域、节点、节点的属性、节点内容的迁移,这些都可以通过依赖注入被传进来,所以你可以根据需要只写要用的参数,有$scope,Z$element, $attrs, $transclude。 
调用该自定义指令的指令需要放在该指令之间。假定firstDirective指令是要被调用的自定义指令,expander是调用者指令。

link属性用法:
link后的方法在指令中负责执行DOM 操作和注册事件监听器等。link函数有五个参数(scope,element,attrs,controller,linker)。link 方法的参数解释: 
scope: 它与自定义指令里的scope属性是一个东西。它是指令scope的引用,所以可改名为sco等其他名字。scope 变量在初始化时是不被定义的,link 方法会注册监视器监视值变化事件。 
element: 包含指令的DOM元素的引用, link 方法一般通过jQuery 操作实例(如果没有加载jQuery,还可以使用Angular’s jqLite )。 
controller: 在有嵌套指令的情况下使用。这个参数作用在于把子指令的引用提供给父指令,允许指令之间进行交互,如前面的例子。 
注意:当调用link 方法时, 通过值传递(”@”)的scope 变量将不会被初始化,它们将会在指令的生命周期中另一个时间点进行初始化,如果你需要监听这个事件,可以使用scope.$watch 方法。


下面看网友创建一个directive,这个directive允许用户拖拽元素,让我们以此来说明如何在directive中创建事件监听。

index.html

<span my-draggable>Drag ME</span>
script.js

angular.module('dragModule', [])
.directive('myDraggable', ['$document', function($document) {
  return {
    link: function(scope, element, attr) {
      var startX = 0, startY = 0, x = 0, y = 0;

      element.css({
       position: 'relative',
       border: '1px solid red',
       backgroundColor: 'lightgrey',
       cursor: 'pointer'
      });

      element.on('mousedown', function(event) {
        // Prevent default dragging of selected content
        event.preventDefault();
        startX = event.pageX - x;
        startY = event.pageY - y;
        $document.on('mousemove', mousemove);
        $document.on('mouseup', mouseup);
      });

      function mousemove(event) {
        y = event.pageY - startY;
        x = event.pageX - startX;
        element.css({
          top: y + 'px',
          left:  x + 'px'
        });
      }

      function mouseup() {
        $document.off('mousemove', mousemove);
        $document.off('mouseup', mouseup);
      }
    }
  };
}]);
最后让我们创建一个directive,此directive根据我们点击的tab展示不同的内容。

index.html

<my-tabs>
  <my-pane title="Hello">
    <h4>Hello</h4>
    <p>Lorem ipsum dolor sit amet</p>
  </my-pane>
  <my-pane title="World">
    <h4>World</h4>
    <em>Mauris elementum elementum enim at suscipit.</em>
    <p><a href ng-click="i = i + 1">counter: {{i || 0}}</a></p>
  </my-pane>
</my-tabs>
script.js

angular.module('docsTabsExample', [])
.directive('myTabs', function() {
  return {
    restrict: 'E',
    transclude: true,
    scope: {},
    controller: function($scope) {
      var panes = $scope.panes = [];

      $scope.select = function(pane) {
        angular.forEach(panes, function(pane) {
          pane.selected = false;
        });
        pane.selected = true;
      };

      this.addPane = function(pane) {
        if (panes.length === 0) {
          $scope.select(pane);
        }
        panes.push(pane);
      };
    },
    templateUrl: 'my-tabs.html'
  };
})
.directive('myPane', function() {
  return {
    require: '^myTabs',
    restrict: 'E',
    transclude: true,
    scope: {
      title: '@'
    },
    link: function(scope, element, attrs, tabsCtrl) {
      tabsCtrl.addPane(scope);
    },
    templateUrl: 'my-pane.html'
  };
});
my-tabs.html

<div class="tabbable">
  <ul class="nav nav-tabs">
    <li ng-repeat="pane in panes" ng-class="{active:pane.selected}">
      <a href="" ng-click="select(pane)">{{pane.title}}</a>
    </li>
  </ul>
  <div class="tab-content" ng-transclude></div>
</div>
my-pane.html

div class="tab-pane" ng-show="selected" ng-transclude>
</div>
当我们在directive中使用require属性,如果没有找到指定的controller,$compile将会报错,^前缀指明在父controller中寻找,没有^前缀则在自己的元素中查找。

如果directive中指定了require属性,那么可以在其link方法中将该controller作为第四个参数传入。如果需要多个controller,那么require属性后面可以跟一个数组,同样link方法的第四个参数传入也是一个数组,

传入需要的controller列表。


参考:http://blog.csdn.net/zcl_love_wx/article/details/51331539



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值