我正在尝试使用 Angularjs 创建拖放指令。在这种情况下,可拖动对象由 ng-repeat 指令生成,遍历数组。http://jsbin.com/ECAWuDE/1/edit上的代码 按预期工作。但它需要一个可拖动的包装父范围。
当我尝试通过使用服务( http://jsbin.com/AJoTIw/2/edit )摆脱包装范围时,我无法再访问该数组。
我在第二版代码中做错了什么?
我正在尝试使用 Angularjs 创建拖放指令。在这种情况下,可拖动对象由 ng-repeat 指令生成,遍历数组。http://jsbin.com/ECAWuDE/1/edit上的代码 按预期工作。但它需要一个可拖动的包装父范围。
当我尝试通过使用服务( http://jsbin.com/AJoTIw/2/edit )摆脱包装范围时,我无法再访问该数组。
我在第二版代码中做错了什么?
首先,您的绑定在$scope
变量的上下文中进行评估。您不能拥有服务并直接绑定到其数据。所以实际上你需要一个包装元素。因此,您要么使用 div 要么使用重复元素的任何父级。我已经更新了你的 jsbin 看这里。
您仍然可以通过使用控制器在没有服务的情况下执行此操作。
我已设法更改您的代码以使用该服务,并且它现在正在运行。
我创建了一个名为“make-it-drag”的新指令,它使 draggables 指令的“ng-repeat”中的每个元素都......呃......可拖动。;)
所以我使用'draggables'控制器函数只是$scope.blocks
用服务返回的数据来设置值。然后,“make-it-drag”指令负责执行所有事件绑定。
你可以看到下面的代码:
<!doctype html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
.droppable {
width: 300px;
height: 300px;
border: 1px solid red;
}
.draggable, .dropped {
display: inline-block;
height: 50px;
width: 50px;
margin: 10px;
}
.hidden {
display: none;
}
.green {background-color: green;}
.blue {background-color: blue;}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0rc1/angular.min.js></script>
<script type="text/javascript">
var myApp = angular.module('myApp', []);
myApp.directive('makeItDrag', [function () {
return {
restrict: 'A',
link: function (scope, elm, attrs) {
elm.attr("draggable", true);
elm.bind("dragstart", function(evt){
evt.dataTransfer.setData("text/plain", JSON.stringify(scope.bl));
});
elm.bind("dragend", function(evt){
var data = evt.dataTransfer.getData("text/plain");
console.log(data);
});
}
};
}])
myApp.directive('draggables', [ 'crmService' ,function (crmService) {
return {
restrict: 'A',
link: function (scope, elm, attrs) {
console.log('I am draggable', crmService.blocks);
},
controller: function($scope, $element, $attrs){
$scope.blocks = crmService.blocks;
}
};
}])
myApp.directive('droppables', [ 'crmService', function (crmService) {
return {
restrict: 'A',
link: function (scope, elm, attrs) {
console.log('I am droppable', crmService.blocks);
scope._blocks = [];
elm.bind("drop", function(evt){
// redirecti engelliyoruz
evt.preventDefault();
data = JSON.parse(evt.dataTransfer.getData("text/plain"));
// directive ve ng-repeat konusunda bir sıkıntı var,
// ng-repeat ile yeni yerel scopayar oluştuğu için sanıyorum
// ki apply gerekiyor
scope.$apply(function(){
scope._blocks.push({color: data.color, name:data.name})
});
return false;
});
elm.bind("dragover", function(evt){
// bu kısmın droppable olduğunu gösteriyor
evt.preventDefault();
});
elm.bind("dragenter", function(){
console.log("enter");
});
elm.bind("dragleave", function(){
console.log("leave");
});
}
};
}])
myApp.factory("crmService", function(){
return {
blocks: [
{"color": "green", name:"resim 1" },
{"color": "blue", name:"resim 2" }
]
}
})
</script>
</head>
<body>
<div draggables>
<div class="draggable {{ bl.color }} " ng-repeat="bl in blocks" make-it-drag></div>
</div>
<div droppables class="droppable">
<div droppable="true" class="dropped {{ _bl.color }}" ng-repeat="_bl in _blocks">
</div>
</div>
</body>
</html>
PS:顺便说一句,我在指令的名称中添加了一个“s”(draggable* s * / droppable* s *),因为它们是 HTML5 保留字 - 使用保留字不是一个好习惯。