angularjs 拖拽实现方案
最近有一个拖拽排序的功能遍历后无法直接读取index 和 item。换了一种思路实现功能
<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body ng-controller="demoController">
<ul class="list">
<li draggable="true" ng-repeat="li in arr track by $index" data-value="{{li.value}}" data-id="{{li.id}}">{{li.value}}{{$index}}</li>
</ul>
<button ng-click="save()">保存数据</button>
<script src="https://cdn.bootcdn.net/ajax/libs/angular.js/1.8.3/angular.min.js"></script>
<script src="/bundle.js"></script>
</body>
</html>
let app = angular.module('myApp', []);
app.controller('demoController', ['$scope', function($scope) {
$scope.arr = [{
value: '赵',
id: 1
}, {
value: '钱',
id: 2
}, {
value: '孙',
id: 3
}, {
value: '李',
id: 4
}, {
value: '周',
id: 5
}];
let list = document.querySelector('.list')
let currentLi;
//拖拽开始
list.addEventListener('dragstart', (e) => {
e.dataTransfer.effectAllowed = 'move'
currentLi = e.target
setTimeout(() => {
currentLi.classList.add('moving')
})
})
//进入元素
list.addEventListener('dragenter', (e) => {
e.preventDefault()
if (e.target === currentLi || e.target === list) {
return
}
let liArray = Array.from(list.childNodes)
let currentIndex = liArray.indexOf(currentLi)
let targetindex = liArray.indexOf(e.target)
if (currentIndex < targetindex) {
list.insertBefore(currentLi, e.target.nextElementSibling)
} else {
list.insertBefore(currentLi, e.target)
}
})
//离开元素
list.addEventListener('dragover', (e) => {
e.preventDefault()
})
//拖拽结束
list.addEventListener('dragend', (e) => {
currentLi.classList.remove('moving')
//操作完毕赋值
for (let k = 0; k < list.children.length; k++) {
$scope.arr[k] = {
value: list.children[k].dataset.value,
id: list.children[k].dataset.id
};
}
})
//保存
$scope.save = function() {
console.log($scope.arr)
}
}]);
方案二(推荐):
<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body ng-controller="demoController">
<ul class="list">
<li draggable="true" ng-repeat="li in arr track by $index" ng-class-even="'even'" ng-class-odd="'odd'" ng-dragend="end(li,$index)" ng-dragenter="enter(li,$index)" ng-dragstart="start(li,$index)">{{li.value}}{{$index}}</li>
</ul>
<button ng-click="save()">保存数据</button>
<script src="https://cdn.bootcdn.net/ajax/libs/angular.js/1.8.3/angular.min.js"></script>
<script src="/bundle.js"></script>
</body>
</html>
let app = angular.module('myApp', []);
var ngDragEventDirectives = {};
//在全局模块中增加可拖拽指令
app.directive(ngDragEventDirectives);
angular.forEach(
'drag dragend dragenter dragexit dragleave dragover dragstart drop'.split(' '),
function(eventName) {
var directiveName = 'ng' + eventName.charAt(0).toUpperCase() + eventName.slice(1);
ngDragEventDirectives[directiveName] = ['$parse', '$rootScope', function($parse, $rootScope) {
return {
restrict: 'A',
compile: function($element, attr) {
var fn = $parse(attr[directiveName], null, true);
return function ngDragEventHandler(scope, element) {
element.on(eventName, function(event) {
var callback = function() {
fn(scope, { $event: event });
};
scope.$apply(callback);
});
};
}
};
}];
}
);
app.controller('demoController', ['$scope', function($scope) {
$scope.arr = [{
value: '赵',
id: 1
}, {
value: '钱',
id: 2
}, {
value: '孙',
id: 3
}, {
value: '李',
id: 4
}, {
value: '周',
id: 5
}];
$scope.currentItem = null;
$scope.currentIndex = null;
//开始拖拽
$scope.start = (item, index) => {
}
//拖拽结束
$scope.end = (item, index) => {
swapArray($scope.arr, $scope.currentIndex, index)
}
//进入
$scope.enter = (item, index) => {
$scope.currentItem = item;
$scope.currentIndex = index;
}
//保存数据
$scope.save = function() {
console.log($scope.arr)
}
//数据替换
function swapArray(arr, index1, index2) {
arr[index1] = arr.splice(index2, 1, arr[index1])[0];
console.log(arr)
return arr;
}