是否有任何Angular JS Tabs指令允许对它们重新排序(如浏览器的选项卡)
如果不是一个开始实施将是伟大的
<tabset> <tab ng-repeat="tab in vm.tabs" active="tab.active" sortable-tab> </tab> <tab disabled="true" ng-click"vm.addNewTab()" class="nonSortable-addTab-plusButton"></tab> </tabset>
如何使它们可重新定位?
编辑:Bounty添加使用上面的原始tabset语法.
使用Angular UI Bootstrap选项卡,只有一个sortable-tab指令:
<tabset> <tab sortable-tab ng-repeat="tab in tabs" heading="{{tab.title}}" active="tab.active" disabled="tab.disabled"> <p>{{tab.content}}</p> </tab> <tab disabled="true"> <tab-heading> <i class="glyphicon glyphicon-plus"></i> </tab-heading> </tab> </tabset>
首先,它需要一些技巧/黑客来与ngRepeat集成,因此它可以重新排序数组.它(重新)解析ng-repeat属性,并从范围中获取数组,就像ngRepeat一样
// Attempt to integrate with ngRepeat // https://github.com/angular/angular.js/blob/master/src/ng/directive/ngRepeat.js#L211 var match = attrs.ngRepeat.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?\s*$/); var tabs; scope.$watch(match[2],function(newTabs) { tabs = newTabs; });
然后,您还可以在范围上观察$index变量,以确保您总是拥有当前元素的最新索引:
var index = scope.$index; scope.$watch('$index',function(newIndex) { index = newIndex; });
然后使用HTML5 drag and drop,通过setData和getData将元素的索引作为其数据传递
attrs.$set('draggable',true); // Wrapped in $apply so Angular reacts to changes var wrappedListeners = { // On item being dragged dragstart: function(e) { e.dataTransfer.effectAllowed = 'move'; e.dataTransfer.dropEffect = 'move'; e.dataTransfer.setData('application/json',index); element.addClass('dragging'); },dragend: function(e) { e.stopPropagation(); element.removeClass('dragging'); },dragleave: function(e) { element.removeClass('hover'); },drop: function(e) { e.preventDefault(); e.stopPropagation(); var sourceIndex = e.dataTransfer.getData('application/json'); move(sourceIndex,index); element.removeClass('hover'); } }; // For performance purposes,do not // call $apply for these var unwrappedListeners = { dragover: function(e) { e.preventDefault(); element.addClass('hover'); },/* Use .hover instead of :hover. :hover doesn't play well with moving DOM from under mouse when hovered */ mouseenter: function() { element.addClass('hover'); },mouseleave: function() { element.removeClass('hover'); } }; angular.forEach(wrappedListeners,function(listener,event) { element.on(event,wrap(listener)); }); angular.forEach(unwrappedListeners,listener); }); function wrap(fn) { return function(e) { scope.$apply(function() { fn(e); }); }; }
注意:使用悬停类有一些黑客攻击,而不是:悬停一些悬停效果.这部分是由于CSS:在从鼠标下方重新排列元素后,元素上没有删除悬停样式,至少在Chrome中是这样.
实际移动选项卡的功能,获取ngRepeat使用的数组,并重新排序:
function move(fromIndex,toIndex) { // http://stackoverflow.com/a/7180095/1319998 tabs.splice(toIndex,tabs.splice(fromIndex,1)[0]); };
你可以看到这一切in a Plunker