angularJs自定义指令

1 篇文章 0 订阅
1 篇文章 0 订阅

使用过 AngularJS 的朋友应该最感兴趣的是它的指令。现今市场上的前端框架也只有AngularJS 拥有自定义指令的功能,并且AngularJS 是目前唯一提供Web应用可复用能力的框架。

目前有很多JavaScript 产品提供插件给Web开发人员。例如, Bootstrap 就是当前比较流行的提供样式和JavaScript插件的前端开发工具包。但是开发人员在使用Booostrap中的插件时, 必须切换到JavaScript 模式来写 jQuery 代码来激活插件虽然jQuery代码写起来十分简单,但是必须和HTML进行同步,这是一个单调乏味且容易出错的过程。直接上代码

HTML代码

<body ng-app="components"> 
  <h3>BootStrap Tab Component</h3> 
  <tabs> 
    <pane title="First Tab"> 
      <div>This is the content of the first tab.</div> 
    </pane> 
    <pane title="Second Tab"> 
      <div>This is the content of the second tab.</div> 
    </pane> 
  </tabs> 
</body>

  JavaScript 代码如下:
angular.module('components', []). 
  directive('tabs', function() { 
    return { 
      restrict: 'E', 
      transclude: true, 
      scope: {}, 
      controller: [ "$scope", 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); 
        } 
      }], 
      template: 
        '<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>', 
      replace: true 
    }; 
  }). 
  directive('pane', function() { 
    return { 
      require: '^tabs', 
      restrict: 'E', 
      transclude: true, 
      scope: { title: '@' }, 
      link: function(scope, element, attrs, tabsCtrl) { 
        tabsCtrl.addPane(scope); 
      }, 
      template: 
        '<div class="tab-pane" ng-class="{active: selected}" ng-transclude>' + 
        '</div>', 
      replace: true 
    }; 
  })

创建自定义AngularJS 指令

//创建指令模块 (或者检索现有模块) 
var m = angular.module("myApp");

// 创建"my-dir"指令 
myApp.directive("myDir", function() { 
  return { 
    restrict: "E",        // 指令是一个元素 (并非属性) 
    scope: {              // 设置指令对于的scope 
      name: "@",          // name 值传递 (字符串,单向绑定) 
      amount: "=",        // amount 引用传递(双向绑定) 
      save: "&"           // 保存操作 
    }, 
    template:             // 替换HTML (使用scope中的变量) 
      "<div>" + 
      "  {{name}}: <input ng-model='amount' />" + 
      "  <button ng-click='save()'>Save</button>" + 
      "</div>", 
    replace: true,        // 使用模板替换原始标记 
    transclude: false,    // 不复制原始HTML内容 
    controller: [ "$scope", function ($scope) { …  }], 
    link: function (scope, element, attrs, controller) {…} 
  } 
});

注意这个自定义指令遵循一种格式:以"my" 为前缀,类似于命名空间,因此如果你在应用中引用了多个模块指令,你可以通过前缀很容易的判断出它是在哪定义的。这不是硬性要求,但是这样做可以带来很多便利。

指令的构造函数会返回带有属性的JavaScript 对象。这些内容在AngularJS 主页中都有清晰说明。以下是我对一些属性的理解:

  1. restrict: 说明指令在HTML中的应用形式,备选项有"A"、"E" 和 "C", "M" ,分别代表 attribute、element、class和comment(默认值为"A")。我们将更多的关注attributes-如何创建UI元素。
  2. scope: 创建指令的作用范围,scope在指令中作为属性标签传递。Scope 是创建可以复用指令的必要条件,每个指令(不论是处于嵌套指令的哪一级)都有其唯一的作用域,它不依赖于父scope。scope 对象定义names 和types 变量。上面的例子即创建了3个scope变量。
    • name: "@" (值传递,单向绑定):
      "@"符号表示变量是值传递。指令会检索从父级scope中传递而来字符串中的值。指令可以使用该值但无法修改,是最常用的变量。
    • amount: "=" (引用,双向绑定)
      "="符号表示变量是引用传递。指令检索主Scope中的引用取值。值可以是任意类型的,包括复合对象和数组。指令可以更改父级Scope中的值,所以当指令需要修改父级Scope中的值时我们就需要使用这种类型。
    • save: "&" (表达式)
      “&”符号表示变量是在父级Scope中启作用的表达式。它允许指令实现比修改值更高级的操作。
  3. template: 替代原始模板中的标记的字符串。替换功能将替换所有旧元素为新值。注意template是如何使用Scope中定义的变量的。这允许你无需写任何额外的代码即可创建macro-style 风格指令。replace: 说明是否替换原始标记中的值或是追加原始标记中的值。默认值是false,这时原始标记将被保留。
  4. transclude: 说明自定义指令是否复制原始标记中的内容。例如,之前展示的“tab”指令设置了transclude 为 true,因为tab 元素包含其他HTML 元素。 "dateInput" 指令则需要在初始化时为空,所以需要设置transclude 为false。
  5. link: 该方法在指令中扮演着重要的角色。它负责执行DOM 操作和注册事件监听器等。link 方法包含以下参数:
    • scope: 指令Scope的引用。scope 变量在初始化时是不被定义的,link 方法会注册监视器监视值变化事件。
    • element: 包含指令的DOM元素的引用, link 方法一般通过jQuery 操作实例(如果没有加载jQuery,还可以使用Angular's jqLite )。
    • controller: 在有嵌套指令的情况下使用。这个参数作用在于把子指令的引用提供给父指令,允许指令之间进行交互
注意,当调用link 方法时, 通过值传递("@")的scope 变量将不会被初始化,它们将会在指令的生命周期中另一个时间点进行初始化,如果你需要监听这个事件,可以使用scope.$watch 方法。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值