是否可以 move/sort/reorder Angular UI 标签拖放?
Is it possible to move/sort/reorder Angular UI Tabs with drag and drop?
以前版本的 Angular UI 似乎可行(参见 here),但我尝试使用 uib-tabset
但它不起作用。有什么想法吗?
这行不通:
<uib-tabset sortable-tab>
<uib-tab heading="Title 1">
Some text 1
</uib-tab>
<uib-tab heading="Title 2">
Some text 2
</uib-tab>
</uib-tabset>
它仍然有效。您必须应用该指令。您的示例中的指令尚未 built 到 ui。这是一个 Plunker,它与新版本一起工作。
在你的HTML中:
<uib-tabset>
<uib-tab sortable-tab ng-repeat="tab in data.tabs" heading="{{tab.title}}" active="tab.active" disabled="tab.disabled">
<p>{{tab.content}}</p>
</uib-tab>
<uib-tab disabled="true">
<uib-tab-heading>
<i class="glyphicon glyphicon-plus"></i>
</uib-tab-heading>
</uib-tab>
</uib-tabset>
您还必须在控制器中包含该指令:
app.directive('sortableTab', function($timeout, $document) {
return {
link: function(scope, element, attrs, controller) {
// 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;
});
var index = scope.$index;
scope.$watch('$index', function(newIndex) {
index = newIndex;
});
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');
},
// On item being dragged over / dropped onto
dragenter: function(e) {
},
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);
});
};
}
function move(fromIndex, toIndex) {
//
tabs.splice(toIndex, 0, tabs.splice(fromIndex, 1)[0]);
};
}
}
});
该指令还对标签使用 ng-repeat
标签是动态的:
$scope.data = [];
$scope.data.tabs = [
{ title:'Dynamic Title 1', content:'Dynamic content 1', active:true},
{ title:'Dynamic Title 2', content:'Dynamic content 2'},
{ title:'Dynamic Title 3', content:'Dynamic content 3'}
];
以前版本的 Angular UI 似乎可行(参见 here),但我尝试使用 uib-tabset
但它不起作用。有什么想法吗?
这行不通:
<uib-tabset sortable-tab>
<uib-tab heading="Title 1">
Some text 1
</uib-tab>
<uib-tab heading="Title 2">
Some text 2
</uib-tab>
</uib-tabset>
它仍然有效。您必须应用该指令。您的示例中的指令尚未 built 到 ui。这是一个 Plunker,它与新版本一起工作。
在你的HTML中:
<uib-tabset>
<uib-tab sortable-tab ng-repeat="tab in data.tabs" heading="{{tab.title}}" active="tab.active" disabled="tab.disabled">
<p>{{tab.content}}</p>
</uib-tab>
<uib-tab disabled="true">
<uib-tab-heading>
<i class="glyphicon glyphicon-plus"></i>
</uib-tab-heading>
</uib-tab>
</uib-tabset>
您还必须在控制器中包含该指令:
app.directive('sortableTab', function($timeout, $document) {
return {
link: function(scope, element, attrs, controller) {
// 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;
});
var index = scope.$index;
scope.$watch('$index', function(newIndex) {
index = newIndex;
});
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');
},
// On item being dragged over / dropped onto
dragenter: function(e) {
},
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);
});
};
}
function move(fromIndex, toIndex) {
//
tabs.splice(toIndex, 0, tabs.splice(fromIndex, 1)[0]);
};
}
}
});
该指令还对标签使用 ng-repeat
标签是动态的:
$scope.data = [];
$scope.data.tabs = [
{ title:'Dynamic Title 1', content:'Dynamic content 1', active:true},
{ title:'Dynamic Title 2', content:'Dynamic content 2'},
{ title:'Dynamic Title 3', content:'Dynamic content 3'}
];