0

我正在尝试使用 Angularjs 创建拖放指令。在这种情况下,可拖动对象由 ng-repeat 指令生成,遍历数组。http://jsbin.com/ECAWuDE/1/edit上的代码 按预期工作。但它需要一个可拖动的包装父范围。

当我尝试通过使用服务( http://jsbin.com/AJoTIw/2/edit )摆脱包装范围时,我无法再访问该数组。

我在第二版代码中做错了什么?

4

2 回答 2

1

首先,您的绑定在$scope变量的上下文中进行评估。您不能拥有服务并直接绑定到其数据。所以实际上你需要一个包装元素。因此,您要么使用 div 要么使用重复元素的任何父级。我已经更新了你的 jsbin 看这里

您仍然可以通过使用控制器在没有服务的情况下执行此操作。

于 2013-08-25T09:22:27.580 回答
1

我已设法更改您的代码以使用该服务,并且它现在正在运行。

我创建了一个名为“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 保留字 - 使用保留字不是一个好习惯。

于 2013-08-25T10:34:36.480 回答