一尘不染

角度标签-可排序/可移动

angularjs

是否有任何Angular JS Tabs指令可对其进行重新排序(例如浏览器的选项卡)

如果不是开始实施,那将是很好的

使用angular-ui-bootstap

<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>

如何使它们可重新排序?

编辑:增加了赏金以使用上面的原始tabset语法。


阅读 264

收藏
2020-07-04

共1个答案

一尘不染

使用Angular UI Bootstrap tabset,只需一个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拖放,通过使所述元素的索引作为其数据setDatagetData

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, function(listener, event) {
  element.on(event, listener);
});

function wrap(fn) {
  return function(e) {
    scope.$apply(function() {
      fn(e);
    });
  };
}

注意:关于使用hover类,:hover有些技巧,而不是某些悬停效果。这部分是由于CSS
:hover样式没有从鼠标下方重新排列后,至少在Chrome中未在元素上删除。

实际移动选项卡,获取使用的数组ngRepeat并对其重新排序的函数:

function move(fromIndex, toIndex) {
  // http://stackoverflow.com/a/7180095/1319998
  tabs.splice(toIndex, 0, tabs.splice(fromIndex, 1)[0]);
};

您可以在Plunker中看到所有这些

2020-07-04