我正在尝试使用Angularjs创建拖放指令。此场景中的可拖动是由ng-repeat指令生成的,遍历数组。 http://jsbin.com/ECAWuDE/1/edit处的代码按预期工作。但是它需要一个包装父级作用域。
当我尝试通过使用服务(http://jsbin.com/AJoTIw/2/edit)来摆脱包装范围时,我无法再访问该数组。
我在第二版代码中做错了什么?
答案 0 :(得分:1)
首先,您的绑定是在$scope
变量的上下文中进行评估的。您不能拥有服务并直接绑定到其数据。所以实际上你需要一个包装元素。所以你要么使用div或者repeat元素的任何父元素。我已经更新了你jsbin,请参阅here。
通过使用控制器,您仍然可以在没有服务的情况下执行此操作。
答案 1 :(得分:1)
我已设法更改您的代码以使用该服务,现在它正在运行。
我创建了一个名为'make-it-drag'的新指令,它使draggables指令的'ng-repeat'的每个元素都成为...... erm ... draggable。 ;)
所以我只使用'draggables' controller 函数来设置$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保留字 - 使用保留字不是一种好习惯。