使用AngularJS,点击另一个div后使div移动

6

我在我的项目中使用AngularJS实现了拖放功能,以便让用户能够对项目进行分类。只需要满足我的一个简单需求:

将一个DIV从一个位置移动到另一个位置。

Step 1: User click at division (1) 
Step 2: User click at division (2)

处理流程: 一旦用户在步骤(2)处,Goose将移动到步骤(2)。如果用户在步骤(2)中再次单击Goose,则它将返回到步骤(1)

我应该如何做?

您可以看到我的期望输出:

enter image description here

到目前为止,我的当前代码:

var myApp = angular.module('MyApp',['ngDraggable']).controller('MyCtrl',function($scope){
  
    $scope.centerAnchor = true;
    $scope.toggleCenterAnchor = function () {
        $scope.centerAnchor = !$scope.centerAnchor
    };

    var onDraggableEvent = function (evt, data) {
        console.log("128", "onDraggableEvent", evt, data);
    };
    $scope.$on('draggable:start', onDraggableEvent);
    $scope.$on('draggable:end', onDraggableEvent);
    $scope.droppedObjects0 = [{name:'Goose'},{name:'Rabbit'},{name:'Chick'},{name:'Cat'}];
    $scope.droppedObjects1 = []; //Answer: Cat + Rabbit
    $scope.droppedObjects2 = []; //Answer: Chicken + Goose
    
    
    $scope.AnswerOject1 = [{name:'Arnab'},{name:'Kucing'}];
    $scope.AnswerOject2 = [{name:'Angsa'},{name:'Ayam'}];
    
    $scope.onDropComplete0 = function (data, evt) {
        console.log("127", "$scope", "onDropComplete0", data, evt);
        var index = $scope.droppedObjects0.indexOf(data);
        if (index == -1)
            $scope.droppedObjects0.push(data);
    };
    $scope.onDropComplete1 = function (data, evt) {
        console.log("127", "$scope", "onDropComplete1", data, evt);
        var index = $scope.droppedObjects1.indexOf(data);
        if (index == -1)
            $scope.droppedObjects1.push(data);
    };
    $scope.onDragSuccess0 = function (data, evt) {
        console.log("133", "$scope", "onDragSuccess0", "", evt);
        var index = $scope.droppedObjects0.indexOf(data);
        if (index > -1) {
            $scope.droppedObjects0.splice(index, 1);
        }
    };
    $scope.onDragSuccess1 = function (data, evt) {
        console.log("133", "$scope", "onDragSuccess1", "", evt);
        var index = $scope.droppedObjects1.indexOf(data);
        if (index > -1) {
            $scope.droppedObjects1.splice(index, 1);
        }
    };
    $scope.onDragSuccess2 = function (data, evt) {
        var index = $scope.droppedObjects2.indexOf(data);
        if (index > -1) {
            $scope.droppedObjects2.splice(index, 1);
        }
    };
    $scope.onDropComplete2 = function (data, evt) {
        var index = $scope.droppedObjects2.indexOf(data);
        if (index == -1) {
            $scope.droppedObjects2.push(data);
        }
    };
    var inArray = function (array, obj) {
        var index = array.indexOf(obj);
    };
});
.body
{
    width:500px;
    margin-left:auto; 
    margin-right:auto;
}

[ng-drag] {
    -moz-user-select: -moz-none;
    -khtml-user-select: none;
    -webkit-user-select: none;
    -ms-user-select: none;
    user-select: none;
}

[ng-drag] {
    width: 50px;
    height: 50px;
    background: rgba(255, 255, 255, 0.5);
    color: #131313;
    text-align: center;
    padding-top: 12px;
    display: inline-block;
    margin: 5px 5px;
    cursor: move;
    border: 1px solid #ccc;
    border-radius: 4px;
}

ul.draggable-objects:after {
    display: block;
    content: "";
    clear: both;
}

.draggable-objects li {
    float: left;
    display: block;
    width: 50px;
    height: 50px;
    margin:2px;
}

[ng-drag].drag-over {
    border: solid 1px red;
}

[ng-drag].dragging {
    opacity: 0.5;
}

[ng-drop] {
    background: rgba(198, 255, 198, 0.5);
    text-align: center;
    height: 150px;
    padding-top: 10px;
    display: block;
    margin: 20px auto;
    position: relative;
    border: 1px solid #c3c3c3;
    border-radius: 8px;
}

[ng-drop].drag-enter {
    border: solid 5px red;
}

[ng-drop] span.title {
    display: block;
    position: absolute;
    top: 50%;
    left: 50%;
    width: 200px;
    height: 20px;
    margin-left: -100px;
    margin-top: -10px;
}

[ng-drop] div {
    position: relative;
    z-index: 2;
}
.list-of-drag-item
{
    height: 83px;
    background-color: #f7f7f7;
}
<link href="http://code.ionicframework.com/1.3.1/css/ionic.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ngDraggable/0.1.10/ngDraggable.js"></script>

<div ng-app="MyApp" ng-controller="MyCtrl" class="body">
Categorize the animals based on their reproductive system
<div class="row">
    <div class="col">
        <div class="list-of-drag-item" ng-drop="true" ng-drop-success="onDropComplete0($data,$event)">
            <div ng-click="clickMe()"  ng-repeat="obj in droppedObjects0" ng-drag="true" ng-drag-data="obj"
                ng-drag-success="onDragSuccess0($data,$event)" ng-center-anchor="{{centerAnchor}}">
               {{obj.name}}
            </div>
        </div>
    </div>
</div>
<div class="row" style="text-align: center;">
    <div class="col div-left">
        <span class="title">Animals that give birth
        <div ng-drop="true" ng-drop-success="onDropComplete1($data,$event)">
            <div ng-repeat="obj in droppedObjects1" ng-drag="true" ng-drag-data="obj"
                 ng-drag-success="onDragSuccess1($data,$event)" ng-center-anchor="{{centerAnchor}}">
                {{obj.name}}
            </div>
        </div>
    </div>
    <div class="col div-right">
        <span class="title">Animals that Laying Eggs</span>
        <div ng-drop="true" ng-drop-success="onDropComplete2($data,$event)">
            <div ng-repeat="obj in droppedObjects2" ng-drag="true" ng-drag-data="obj"
                 ng-drag-success="onDragSuccess2($data,$event)" ng-center-anchor="{{centerAnchor}}">
                {{obj.name}}
            </div>
        </div>
    </div>
</div>
  </div>


很抱歉,我不太明白您想要做什么。您能否尝试更详细地解释一下? - thepio
用户首先点击“鹅”然后点击下面的DIV,这只“鹅”将移动到那个DIV。 - Nere
哦,好的!谢谢你的澄清。 - thepio
只是注意一下--根据文档,ngDraggable目前没有由作者进行维护--并且它有64个未解决的问题。你可能最好寻找另一个库,或者只是使用本地实现。 - Alexander Nied
1个回答

4
我修改了你的代码以实现这个功能。首先,你没有检查拖放事件处理程序中是否存在对象,如果只是单击一个元素,则会触发拖放事件。可能是拖放库中的错误。 然后我添加了元素的点击处理程序,以保存给定引用的 $scope.activeElement 和它们包含在其中的容器的引用 containerOfActiveElement。此外,容器上还有点击处理程序,用于将活动元素从容器数组中添加和删除。
模板和 CSS 中也有一些代码,用于设置活动元素的红色背景。它还添加了一个过渡效果,与 Angular 的 $timeout 结合使用,使动画发生。
你有很多重复的代码。你可以像我一样通过传递数组引用来改进它们。

var myApp = angular.module('MyApp', ['ngDraggable']).controller('MyCtrl',function($scope, $timeout){

$scope.activeElement;
var containerOfActiveElement;
var activeHTMLElement;
var getCenterOfELement = function (htmlElement) {
  var rect = htmlElement.getBoundingClientRect(); 
  return {
    x: rect.left + rect.width / 2,
    y: rect.top + rect.height / 2
  }
};
$scope.onElementClick = function(event, data, container) {
  if (!angular.equals(data, $scope.activeElement)) {
    event.stopPropagation(); // you need this for not firing event on container
    $scope.activeElement = data;
    containerOfActiveElement = container;
    activeHTMLElement = event.target;
  } else 
    $scope.activeElement = null;
};
$scope.onTargetClick = function(container, event) {
  if ($scope.activeElement) {
    var activeCenter = getCenterOfELement(activeHTMLElement);
    var targetCenter = getCenterOfELement(event.target);
    var offsetX = targetCenter.x - activeCenter.x;
    var offsetY = targetCenter.y - activeCenter.y;
    activeHTMLElement.style.transform= 'translate('+offsetX+'px,'+offsetY+'px)';
    $timeout(function() {
        container.push($scope.activeElement);
        var index = containerOfActiveElement.indexOf($scope.activeElement);
        containerOfActiveElement.splice(index, 1);
        $scope.activeElement = null;
        containerOfActiveElement = null; 
        activeHTMLElement = null;
    }, 200);
  }
};
  
$scope.centerAnchor = true;
$scope.toggleCenterAnchor = function () {
    $scope.centerAnchor = !$scope.centerAnchor
};

/* can be removed, since it has no effect:
var onDraggableEvent = function (evt, data) {
    console.log("128", "onDraggableEvent", evt, data);
};
$scope.$on('draggable:start', onDraggableEvent);
$scope.$on('draggable:end', onDraggableEvent);
*/
  
$scope.droppedObjects0 = [{name:'Goose'},{name:'Rabbit'},{name:'Chick'},{name:'Cat'}];
$scope.droppedObjects1 = []; //Answer: Cat + Rabbit
$scope.droppedObjects2 = []; //Answer: Chicken + Goose


$scope.AnswerOject1 = [{name:'Arnab'},{name:'Kucing'}];
$scope.AnswerOject2 = [{name:'Angsa'},{name:'Ayam'}];

$scope.onDropComplete0 = function (data, evt) {
    console.log("127", "$scope", "onDropComplete0", data, evt);
    var index = $scope.droppedObjects0.indexOf(data);
    if (index == -1 && data !== null) // gave unwanted result if data was null (new empty object)
        $scope.droppedObjects0.push(data);
};
$scope.onDropComplete1 = function (data, evt) {
    console.log("127", "$scope", "onDropComplete1", data, evt);
    var index = $scope.droppedObjects0.indexOf(data);
    if (index == -1 && data !== null)
        $scope.droppedObjects1.push(data);
};
$scope.onDragSuccess0 = function (data, evt) {
    console.log("133", "$scope", "onDragSuccess0", "", evt);
    var index = $scope.droppedObjects0.indexOf(data);
    if (index > -1 && data) {
        $scope.droppedObjects0.splice(index, 1);
    }
};
$scope.onDragSuccess1 = function (data, evt) {
    console.log("133", "$scope", "onDragSuccess1", "", evt);
    var index = $scope.droppedObjects1.indexOf(data);
    if (index > -1) {
        $scope.droppedObjects1.splice(index, 1);
    }
};
$scope.onDragSuccess2 = function (data, evt) {
    var index = $scope.droppedObjects2.indexOf(data);
    if (index > -1) {
        $scope.droppedObjects2.splice(index, 1);
    }
};
$scope.onDropComplete2 = function (data, evt) {
    var index = $scope.droppedObjects2.indexOf(data);
    if (index == -1 && data !== null) {
        $scope.droppedObjects2.push(data);
    }
};
var inArray = function (array, obj) {
    var index = array.indexOf(obj);
};
$scope.logResults = function() {
     console.log({
        'div1': $scope.droppedObjects0,
        'div2': $scope.droppedObjects1,
        'div3': $scope.droppedObjects2
     });
}
});
.body
{
    width:500px;
    margin-left:auto; 
    margin-right:auto;
}

[ng-drag] {
    -moz-user-select: -moz-none;
    -khtml-user-select: none;
    -webkit-user-select: none;
    -ms-user-select: none;
    user-select: none;
}

[ng-drag] {
    width: 50px;
    height: 50px;
    background: rgba(255, 255, 255, 0.5);
    color: #131313;
    text-align: center;
    padding-top: 12px;
    display: inline-block;
    margin: 5px 5px;
    cursor: move;
    border: 1px solid #ccc;
    border-radius: 4px;
}

ul.draggable-objects:after {
    display: block;
    content: "";
    clear: both;
}

.draggable-objects li {
    float: left;
    display: block;
    width: 50px;
    height: 50px;
    margin:2px;
}

[ng-drag].drag-over {
    border: solid 1px red;
}

[ng-drag].dragging {
    opacity: 0.5;
}

[ng-drop] {
    background: rgba(198, 255, 198, 0.5);
    text-align: center;
    height: 150px;
    padding-top: 10px;
    display: block;
    margin: 20px auto;
    position: relative;
    border: 1px solid #c3c3c3;
    border-radius: 8px;
}

[ng-drop].drag-enter {
    border: solid 5px red;
}

[ng-drop] span.title {
    display: block;
    position: absolute;
    top: 50%;
    left: 50%;
    width: 200px;
    height: 20px;
    margin-left: -100px;
    margin-top: -10px;
}

[ng-drop] div {
    position: relative;
    z-index: 2;
}
.list-of-drag-item
{
    height: 83px;
    background-color: #f7f7f7;
}

.active {
    background-color: red;
    color: white;
    transition: transform .2s ease-in-out;
}
<link href="http://code.ionicframework.com/1.3.1/css/ionic.min.css" rel="stylesheet"/>
   <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
   <script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
   <script src="https://cdnjs.cloudflare.com/ajax/libs/ngDraggable/0.1.10/ngDraggable.js"></script>

<div ng-app="MyApp" ng-controller="MyCtrl" class="body">
    Categorize the animals based on their reproductive system
<div class="row">
<div class="col">
    <div class="list-of-drag-item" ng-drop="true" ng-drop-success="onDropComplete0($data,$event)" ng-click="onTargetClick(droppedObjects0, $event)">
        <div ng-click="onElementClick($event, obj, droppedObjects0)"  ng-repeat="obj in droppedObjects0" ng-drag="true" ng-drag-data="obj"
            ng-drag-success="onDragSuccess0($data,$event)" ng-center-anchor="{{centerAnchor}}" ng-class="{active: activeElement.name === obj.name}">
           {{obj.name}}
        </div>
    </div>
</div>
</div>
<div class="row" style="text-align: center;">
<div class="col div-left">
    <span class="title">Animals that give birth
    <div ng-drop="true" ng-drop-success="onDropComplete1($data,$event)" ng-click="onTargetClick(droppedObjects1, $event)">
        <div ng-repeat="obj in droppedObjects1" ng-drag="true" ng-drag-data="obj" ng-drag-success="onDragSuccess1($data,$event)" ng-center-anchor="{{centerAnchor}}" ng-click="onElementClick($event, obj, droppedObjects1)" ng-class="{active: activeElement.name === obj.name}">
            {{obj.name}}
        </div>
    </div>
</div>
<div class="col div-right">
    <span class="title">Animals that Laying Eggs</span>
    <div ng-drop="true" ng-drop-success="onDropComplete2($data,$event)" ng-click="onTargetClick(droppedObjects2, $event)">
        <div ng-repeat="obj in droppedObjects2" ng-drag="true" ng-drag-data="obj"
             ng-drag-success="onDragSuccess2($data,$event)" ng-center-anchor="{{centerAnchor}}" ng-click="onElementClick($event, obj, droppedObjects2)" ng-class="{active: activeElement.name === obj.name}">
            {{obj.name}}
        </div>
    </div>
</div>
</div>
   <button ng-click="logResults()">log results</button>
</div>


非常好!如果您能在框改变位置时进行动画,那就太棒了!还有一个问题,您能否以JSON类型显示返回的数据?例如[{DIV:1,[{"CHICK","GOOSE"}]]。 - Nere
1
这里,我添加了一个动画和一个按钮,可以记录您的状态。 - Stefan Negele
我会保留您的答案5天。您完美地回答了我的问题。非常感谢! - Nere
1
@Imran 如果你的问题已经得到了确切的回答,为什么不将其标记为已解决并释放相应的悬赏? - arhak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接