0x00 媒介
自定义指令在angular中是比较难的一个点,写了这么长时间也只会一些简朴的单指令,翻出《用AngularJS开辟下一代Web运用》,拿出内里的accordion例子好好啃一下。
这个例子团体比较简朴,然则照样须要相识一些点:
自定义指令语法
指令自力作用域:这里双向绑定用
=
指令transclude
指令controller:require的controller作为link函数的第四个参数
指令link函数:每一个指令都实行一次,而compile只编译一次
0x01 结果
很简朴的点击一个当前睁开,其他摺叠
个中expander是从controller中轮回出来的
预览:https://jsfiddle.net/savokiss/fh5sv52u/
0x02 View
<accordion>
<expander class='expander' ng-repeat='expander in expanders' expander-title='expander.title'>
{{expander.text}}
</expander>
</accordion>
须要两个自定义指令accordion和expander
0x03 Controller
$scope.expanders = [{
title : 'Click me to expand',
text : 'Hi there folks, I am the content that was hidden but is now shown.'
}, {
title : 'Click this',
text : 'I am even better text than you have seen previously'
}, {
title : 'Test',
text : 'test'
}];
只要一个数组,定义了expander的title和text
0x04 Directives
父级指令accordion
myModule.directive('accordion',function(){
return {
restrict : 'EA',
replace : true,
transclude : true,
template : '<div ng-transclude></div>',
controller : function() {
var expanders = [];
this.gotOpened = function(selectedExpander) {
angular.forEach(expanders, function(expander) {
if (selectedExpander != expander) {
expander.showMe = false;
}
});
};
this.addExpander = function(expander) {
expanders.push(expander);
};
}
};
});
这是手风琴菜单的父级指令,他的作用主要为:
expanders
用来寄存子指令的数据(即子集scope)addExpander
要领用来在子指令挪用link函数时初始化expanders数组gotOpened
要领用来供应给子指令封闭其他expander
子集指令expander
myModule.directive('expander', function(){
return {
restrict : 'EA',
replace : true,
transclude : true,
require : '^?accordion',
scope : {
expanderTitle : '='
},
template : '<div>'
+ '<div class="ex-title" ng-click="toggle()">{{expanderTitle}}</div>'
+ '<div class="ex-body" ng-show="showMe" ng-transclude></div>'
+ '</div>',
link : function(scope, iElement, iAttrs, accordionController) {
scope.showMe = false;
accordionController.addExpander(scope);
scope.toggle = function toggle() {
scope.showMe = !scope.showMe;
accordionController.gotOpened(scope);
};
}
};
});
此指令申明:
require
了accordion指令,所以link函数的末了一个参数就是accordion的controller自力scope中的
expanderTitle
用来双向绑定controller中的titletransclude
用来直接将view中的代码传进来,固然这里只显示了expander的textlink函数供应了flag:
scope.showMe
,用来掌握expander的睁开状况link函数中初始化
showMe
为false,初始化将当前指令的scope添加到父级指令的expander数组中去供应给本身
scope.toggle
要领,用来在切换开关状况,并挪用父级指令封闭其他兄弟
0x05 完
基本上就是这些点,全get到就差不多也能写相似的指令了~