自定义指令实现手风琴菜单 AngularJS
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到就差不多也能写类似的指令了~
相关推荐
问题描述在编写导入指令的时候,需要将函数绑定到指令中,并传入一个参数。<button ng-hide="importing" class="btn btn-warning btn-sm" type="