Angular Js Drag and Drop - передача $index в директиву
Я успешно реализовал функцию перетаскивания в Angular JS.
Основная идея похожа на "Совпадение города со странами". Я могу перетащить город и заглянуть в поле Страна. Но упавший предмет отражается во всей рамке страны. Но так как я использовал ng-repeat, мне трудно получить значение $index в директиве.
Моя реализация здесь:
var module = angular.module('my-app', []);
module.directive('draggable', function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {
element[0].addEventListener('dragstart', scope.handleDragStart, false);
element[0].addEventListener('dragend', scope.handleDragEnd, false);
}
}
});
module.directive('droppable', function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {
element[0].addEventListener('drop', scope.handleDrop, false);
element[0].addEventListener('dragover', scope.handleDragOver, false);
}
}
});
module.controller("MainController", function ($scope) {
$scope.questions = [{
city: "Delhi",
country: "India"
}, {
city: "Tokyo",
country: "Japan"
}, {
city: "Doha",
country: "Qatar"
}, ];
$scope.answers = [];
$scope.handleDragStart = function (e) {
this.style.opacity = '0.9';
e.dataTransfer.setData('text/plain', this.innerHTML);
};
$scope.handleDragEnd = function (e) {
this.style.opacity = '1.0';
};
$scope.handleDrop = function (e) {
e.preventDefault();
e.stopPropagation();
var dataText = e.dataTransfer.getData('text/plain');
$scope.$apply(function () {
$scope.answers[id].country = $scope.questions[$index].country
$scope.answers[id].city = dataText;
});
console.log($scope.answers[$index]);
};
$scope.handleDragOver = function (e) {
e.preventDefault();
e.dataTransfer.dropEffect = 'move';
return false;
};
});
.container {
width: 100%;
border: 1px solid #CCC;
box-shadow: 0 1px 5px #CCC;
border-radius: 5px;
font-family: verdana;
margin: 25px auto;
}
.left {
float: left;
}
.right {
float : right;
}
.container header {
padding: 10px;
}
.container h1 {
padding: 0;
margin: 0;
font-size: 16px;
font-weight: normal;
text-shadow: 0 1px 2px white;
color: #888;
text-align: center;
}
.container section {
padding: 10px 30px;
font-size: 12px;
line-height: 300%;
color: #333;
}
.default {
clear : both;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="my-app">
<div ng-controller="MainController">
<h3>Match the following</h3>
<div class="container">
<header>
<h1>Drag and drop a city into the corresponding Country box</h1>
</header>
<section>
<div draggable="true" ng-repeat="qs in questions">{{qs.city}}</div>
</section>
</div>
<div class="container" ng-repeat="qs in questions">
<header>
<h1>{{qs.country}}</h1>
</header>
<section droppable="true"> <span>{{droppedCity}}</span>
</section>
</div>
<div class="default"> <pre>{{items|json}}</pre>
</div>
</div>
</body>
Любая помощь будет полезна. Благодарю.
1 ответ
Решение
Есть довольно много проблем с вашим кодом. Я бы предложил изучить официальную документацию и некоторые вопросы SO, связанные с пользовательскими директивами и отдельными областями. Вот обновленный код со многими изменениями и обновленной скрипкой:
<body ng-app="my-app">
<div ng-controller="MainController">
<h3>Match the following</h3>
<div class="container">
<header>
<h1>Drag and drop a city into the corresponding Country box</h1>
</header>
<section>
<div draggable="true" ng-repeat="qs in questions" index="{{$index}}">{{qs.city}}</div>
</section>
</div>
<div class="container" ng-repeat="qs in questions">
<header>
<h1>{{qs.country}}</h1>
</header>
<section droppable="true" index="{{$index}}"> <span>{{droppedCity}}</span>
</section>
</div>
<div class="default"> <pre>{{items|json}}</pre>
</div>
</div>
var module = angular.module('my-app', []);
module.directive('draggable', function () {
return {
restrict: 'A',
scope: {
index: '@'
},
link: function (scope, element, attrs) {
element[0].addEventListener('dragstart', scope.handleDragStart, false);
element[0].addEventListener('dragend', scope.handleDragEnd, false);
},
controller: function($scope) {
$scope.handleDragStart = function (e) {
console.log('starting drag', $scope.index);
this.style.opacity = '0.9';
e.dataTransfer.setData('text/plain', this.innerHTML);
};
$scope.handleDragEnd = function (e) {
this.style.opacity = '1.0';
};
}
};
});
module.directive('droppable', function () {
return {
restrict: 'A',
scope: {
index: '@'
},
link: function (scope, element, attrs) {
element[0].addEventListener('drop', scope.handleDrop, false);
element[0].addEventListener('dragover', scope.handleDragOver, false);
},
controller: function($scope) {
$scope.handleDrop = function (e) {
e.preventDefault();
e.stopPropagation();
var dataText = e.dataTransfer.getData('text/plain');
$scope.$parent.answers.push({country: $scope.$parent.questions[$scope.index].country});
$scope.$parent.answers.push({city: $scope.$parent.questions[$scope.index].city});
};
$scope.handleDragOver = function (e) {
e.preventDefault();
e.dataTransfer.dropEffect = 'move';
console.log('dragging over', $scope.$parent.questions[$scope.index].country);
return;
};
}
};
});
module.controller("MainController", function ($scope) {
$scope.questions = [{
city: "Delhi",
country: "India"
}, {
city: "Tokyo",
country: "Japan"
}, {
city: "Doha",
country: "Qatar"
}, ];
$scope.answers = [];
});