您的位置:首页 > Web前端 > JavaScript

anjularjs之directive

2016-06-22 23:54 399 查看
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



自定义指令属性详解

属性值类型说明
restrictstring指令的调用方式,A、C、E、M
prioritynumber指令执行的优先级
templatestring指令使用的模板,可将html页面代码写于此。只能与templateUrl二选其一
templateUrlstring从指定的url地址加载模板。只能与template二选其一
replaceboolean是否用模板替换当前元素。true : 将指令标签替换成temple中定义的内容,页面上不会再有
<my-directive>
标签;false :则append(追加)在当前元素上,即模板的内容包在
<my-directive>
标签内部。默认false。
transcludeboolean是否将当前元素的内容转移到模板中
scopeboolean /object指定指令的作用域。false(默认值): 使用父作用域作为自己的作用域(每个引用自定义指令的标签若其中一个标签改变某一变量值,则会影响其他标签的值 )。true: 新建一个作用域,该作用域继承父作用域(两个引用自定义指令的标签之间的变量互不影响)。JavaScript对象:与父作用域隔离,并指定可以从父作用域访问的变量
controllerfunction定义与其他指令进行交互的接口函数
requirestring指定需要依赖的其他指令
linkfunction以编程的方式操作DOM,包括添加监听器等
compilefunction编程的方式修改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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: