首先,給大家看看指令完成的效果。(請注意區分下面幾張圖片中,對象值的變化)
好了,效果圖已經看完了,如果大家有興趣的話可以繼續往下看,接下來要講的是關於angularJs中filter內置好的order功能,如果熟悉這個功能的同學們可以跳過下面要講的內容
orderBy這個功能其實是內置的過濾器,他可以在html和js代碼中使用
html:{{ orderBy_expression | orderBy : expression : reverse}}
js :$filter('orderBy')(array, expression, reverse)
在這里我們只看html標簽的運用,可以看出來他需要傳入三個值
1.orderBy_expression :你需要排序的數組
2.expression :你需要根據哪個條件排序
3.reverse :正序還是倒序(boolean)
看到這里可能有的同學就知道為什么我要創建效果圖中的這樣的{"orderPredicate":"price","orderReverse":false}對象了。
由於這里不是詳細講過濾的所以想深入理解的話 登錄官方的API吧 : http://docs.angularjs.cn/api/ng/filter/orderBy
現在開始進入主要內容了,首先我們要講的是指令,不廢話先上代碼在分析
js:
angular.module('MyApp',[])
.controller('MyCtrl',function(){
var vm = this;
//排序條件的數組
vm.orderList = [{
"title" : "價格",
"value" : "price"
},{
"title" : "數量",
"value" : "count"
}]
//排序條件對象
vm.orderInfo = {
orderPredicate : "",//排序的值
orderReverse : false//正反序
}
})
.directive('orderList', function() {
return {
controller: function($scope, $element, $attrs, $transclude) {
var lists = [];//排序條件的列表
this.getOpened = function(selectedItem) {
//控制只能點擊一個排序條件
angular.forEach(lists, function(item, key) {
if (selectedItem != item) {
item.showMe = false;
}
});
}
//提供方法,在item生成的時候,將值放入lists中
this.addItem = function(item) {
lists.push(item);
}
},
restrict: 'AE',
template: '<ul class="list-group" ng-transclude></ul>',
replace: true,
transclude: true,
link: function($scope, iElm, iAttrs, controller) {}
};
})
.directive('orderListItem', function() {
return {
scope: {
orderVaule: '=',//即將排序數組中的排序條件
orderReverse: '=',//排序條件的值
orderPredicate: '=',//控制排序的正序或倒序
iconUp: '@',//升序圖標
iconDown: '@',//降序圖標
},
controller: function($scope, $element, $attrs, $transclude) {},
require: '?^orderList',//'^'判斷是否存在父容器oederList,'?'可以避免orderList不存在的時候不報錯
restrict: 'AE',
template: '<li class="list-group-item" ng-click="toogle(orderVaule)">' +
'<span ng-transclude></span>' +
'<i ng-show="showMe" class="glyphicon pull-right" ng-class="{true:\'{{iconUp}}\',false:\'{{iconDown}}\'}[orderReverse]"></i>' +
'</li>',
transclude: true,
link: function($scope, iElm, iAttrs, controller) {
//item渲染剛開始所有的圖標都不顯示
$scope.showMe = false;
//講渲染的item加入父容器的lists中
controller.addItem($scope);
//點擊item事件
$scope.toogle = function(value) {
//正反序切換
$scope.orderReverse = !$scope.orderReverse;
//將值賦予排序條件
$scope.orderPredicate = value;
//並顯示圖標
$scope.showMe = true;
//關閉其他item的圖標
controller.getOpened($scope);
}
}
};
})
html:
<body ng-controller="MyCtrl as vm">
<order-list>
<order-list-item ng-repeat="item in vm.orderList" icon-up="glyphicon-arrow-up" icon-down="glyphicon-arrow-down" order-vaule="item.value" order-reverse="vm.orderInfo.orderReverse" order-predicate="vm.orderInfo.orderPredicate">
{{item.title}}
</order-list-item>
</order-list>
{{vm.orderInfo}}
</body>
可能有些同學疑惑 ng-controller="MyCtrl as vm" 這是什么意思,其實這是angularJs推薦的寫法,為了避免與$scope的原型繼承搞混。畢竟全部都是$scope也不太美觀,實際上是這樣的 var vm =$scope.vm = {}
大部分的講解都在注釋上了,如果有問題的可以在下方提問;另外這里的圖標是不支持圖片的,只支持圖標,需要引入bootstrap.css和里面的圖標功能。
