AngularJS 创建自定义指令
以下文档参考
https://www.cnblogs.com/powertoolsteam/p/angularjs-custom-directive.html
AngularJS 官方创建指令的案例(样式参考Booostrap)
HTML 代码如下:
1<body ng-app="components">
2 <h3>BootStrap Tab Component</h3>
3 <tabs>
4 <pane title="First Tab">
5 <div>This is the content of the first tab.</div>
6 </pane>
7 <pane title="Second Tab">
8 <div>This is the content of the second tab.</div>
9 </pane>
10 </tabs>
11</body>
JavaScript 代码如下:
1angular.module('components', []).
2 directive('tabs', function() {
3 return {
4 restrict: 'E',
5 transclude: true,
6 scope: {},
7 controller: [ "$scope", function($scope) {
8 var panes = $scope.panes = [];
9
10 $scope.select = function(pane) {
11 angular.forEach(panes, function(pane) {
12 pane.selected = false;
13 });
14 pane.selected = true;
15 }
16
17 this.addPane = function(pane) {
18 if (panes.length == 0) $scope.select(pane);
19 panes.push(pane);
20 }
21 }],
22 template:
23 '<div class="tabbable">' +
24 '<ul class="nav nav-tabs">' +
25 '<li ng-repeat="pane in panes" ng-class="{active:pane.selected}">'+
26 '<a href="" ng-click="select(pane)">{{pane.title}}</a>' +
27 '</li>' +
28 '</ul>' +
29 '<div class="tab-content" ng-transclude></div>' +
30 '</div>',
31 replace: true
32 };
33 }).
34 directive('pane', function() {
35 return {
36 require: '^tabs',
37 restrict: 'E',
38 transclude: true,
39 scope: { title: '@' },
40 link: function(scope, element, attrs, tabsCtrl) {
41 tabsCtrl.addPane(scope);
42 },
43 template:
44 '<div class="tab-pane" ng-class="{active: selected}" ng-transclude>' +
45 '</div>',
46 replace: true
47 };
48 })
运行后的效果如下:

创建自定义AngularJS 指令
文章开头的自定义指令十分的简单。它仅仅实现了同步的功能。一般指令是包含更多元素的:
1//创建指令模块 (或者检索现有模块)
2var m = angular.module("myApp");
3
4// 创建"my-dir"指令
5myApp.directive("myDir", function() {
6 return {
7 restrict: "E", // 指令是一个元素 (并非属性)
8 scope: { // 设置指令对于的scope
9 name: "@", // name 值传递 (字符串,单向绑定)
10 amount: "=", // amount 引用传递(双向绑定)
11 save: "&" // 保存操作
12 },
13 template: // 替换HTML (使用scope中的变量)
14 "<div>" +
15 " {{name}}: <input ng-model='amount' />" +
16 " <button ng-click='save()'>Save</button>" +
17 "</div>",
18 replace: true, // 使用模板替换原始标记
19 transclude: false, // 不复制原始HTML内容
20 controller: [ "$scope", function ($scope) { … }],
21 link: function (scope, element, attrs, controller) {…}
22 }
23});
效果如下:

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