问题
I am using Wijmo Tree-View
I am trying to implement the drag and drop functionally with a server side validation, I am unable to get the move to wait for the success for failure from the server side call.
This is my Html
<wj-tree-view control="tv" items-source="data.DeviceInstance"
display-member-path="'Name'"
child-items-path="'Children'"
lazy-load-function="ExpandTreeItemSelected"
format-item="FormatTreeData(s, e)"
allow-Dragging="true"
drop="Drop(s,e)"
drag-over="dragOver(s,e)">
</wj-tree-view>
And this is the drop function
$scope.Drop = function (s, e) {
console.log(e);
$http({
url: NavMenuSelectionFac.AjaxURL("DeviceInstance/DeviceInstance/MoveDeviceInstance"),
cache: false,
method: 'POST',
data: { "deviceInstanceToMove": e._src.dataItem, "NewParentPK": e._tgt.dataItem.pk },
responseType: 'JSON',
}).then(function (response) {
if (response.data.Result === 1) {
Notification.success(response.data.Message);
e.cancel = false;
}
else {
Notification.error(response.data.Message);
e.cancel = true;
}
}, function (response) {
//TODO : Something here
});
};
Setting e.cancel works to fail a move, but how do I get this to wait for the http request. If the even accepted a return I could return the promise, of the http request but it is based off a property on a parameter
回答1:
Theoretically you cannot ask an async event to wait for another async operation inside another async operation without invoking a thread sleep call. I am also assuming you won't be in favour of that. So here is what I propose, on a drop operation, call an http operation and cancel the drop operation. Meanwhile pass your event args to the http operation and raise the same drop operation manually in your http response call back. Here is the fiddle that would do:
http://jsfiddle.net/gfgLwzss/
JS
$scope.dragStartFunction=function(s, e) {
if (e && e.node && e.node.hasChildren) {
if (!document.getElementById('allowDraggingParentNodes').checked) {
e.cancel = true; // prevent dragging parent nodes
} else {
e.node.isCollapsed = true; // collapse parent nodes when dragging
}
}
};
$scope.dragOverFunction= function(s, e) {
if (!document.getElementById('allowDroppingIntoEmpty').checked &&
!e.dropTarget.hasChildren &&
e.position == wijmo.nav.DropPosition.Into) {
e.position = wijmo.nav.DropPosition.Before;
}
};
$scope.dropFunction=function(s,e){
if(e.cancel){
return;
}
var args=new wijmo.nav.TreeNodeDragDropEventArgs(e.dragSource,e.dropTarget,e.position);
if(!e.again){
args.again=true;
//async call
$http({
url:"https://my.api.mockaroo.com/random_validate.json?key=8c9c7af0",
cache:false,
method:"GET",
responseType:"JSON"
}).then((response)=>{
//check async validation
//note that arrow function is used in then callback, use bind() method if you don't want to use arrow functions
if(response.data.result === true){
//validation success
console.log("validation succeed\ncontinue with event");
args.cancel=false;
}
else{
//validation fails
//stop event
console.log("validation failed\ncancel event");
args.cancel=true;
}
s.onDrop(args);
}).catch(function(err){
console.log(err);
});
}
else{
//do something that needs to be done in case of successful validation
console.log("raised after asyn validation success ");
var draggedItem=e.dragSource.dataItem;
e.dragSource.itemsSource.splice(e.dragSource.index,1);
e.dropTarget.itemsSource.splice(e.dropTarget.index,0,draggedItem);
s.loadTree();
}
//cancel default event
e.cancel=true;
}
HTML
<!-- mark this as an Angular application and give it a controller -->
<div ng-app="app" ng-controller="appCtrl" class="container">
<wj-tree-view items-source="data"
display-member-path="header"
child-items-path="'items'"
allow-Dragging="true"
drag-start="dragStartFunction(s,e)"
drag-over="dragOverFunction(s,e)"
drop="dropFunction(s,e)"
>
</wj-tree-view>
</div>
来源:https://stackoverflow.com/questions/48625929/wijmo-wj-tree-view-angularjs-drop-wait-for-http-callback