Reputation: 3
I'm just working on a projet in Angular 1. The task is to do a DOM tree from json object and manipulate with it through native drag'n'drop DOM operations (with out jQuery and etc). I've been done parsing json-> dom function, loading json from server, some drag'n'drop event handlers. Now my question is how to update a json object (from this object I get a ul>li tree structure) when I done a DROP event. Now, code
View
<div ng-controller="TreeController">
<ng-dom-tree
style="background-color: #000"
ng-model = "treeJson"
class="tree"
ng-draggable
ng-droppable>
</ng-dom-tree>
</div>
Controller
.controller('TreeController', TreeController);
TreeController.$inject = ['treeService', '$scope'];
function TreeController(treeService, $scope) {
$scope.treeJson = '';
treeService.getTree().success(function (data) {
$scope.treeJson = data;
});
}
Main directive
.directive('ngDomTree', ngDomTree)
ngDomTree.$inject = [];
function ngDomTree() {
var isEmpty = function (object) {
for (var key in object) {
return false;
}
return true;
};
function createTree(tree, list) { /*creating tree -> json to dom*/}
return {
restrict: 'E',
replace: true,
link: function (scope, elt, attrs) {
scope.$watch('treeJson', function (data) {
if (isEmpty(data))
return;
**CAN'T HANDLE DATA CHANGING HERE**
elt.append(document.createElement('ul'));
createTree(data, document.getElementsByTagName('ul')[0]);
});
}
}
}
Sup directive
.directive('ngDroppable', ngDroppable)
ngDroppable.$inject = [];
function ngDroppable() {
var parseTreeToJson = function(tree){/* dom to json */}
return {
restrict: 'A',
link: function (scope, elt, attrs) {
elt.on('mouseover', function (e) {
var droppableElt = e.target || event.target;
if (!droppableElt.classList.contains('tree__node') && !droppableElt.classList.contains('tree__branch'))
return;
droppableElt.addEventListener(
'dragover',
function (e) {
this.classList.add('navigator');
e.dataTransfer.dropEffect = 'move';
if (e.preventDefault)
e.preventDefault();
this.classList.add('over');
return false;
},
false
);
droppableElt.addEventListener(
'dragenter',
function (e) {
this.classList.add('over');
return false;
},
false
);
droppableElt.addEventListener(
'dragleave',
function (e) {
this.classList.remove('over');
this.classList.remove('navigator');
return false;
},
false
);
droppableElt.addEventListener(
'drop',
function (e) {
if (e.stopPropagation) e.stopPropagation();
this.classList.remove('over');
let item = document.getElementById(e.dataTransfer.getData('Text'));
this.appendChild(item);
item.id = '';
//updating here
scope.treeJson = parseTreeToJson(elt[0].children[0]);
return false;
},
false
);
});
}
}
}
So, In Sup directive when drop event created, and I'm reinit treeJson variable, after that I need in main directive reinitializing the tree and also in controller get new json structure from this variable, because $watch is used, but it isn't happened.
PLEASE HELP
THNKS FOR ATTENTION :)
Upvotes: 0
Views: 428
Reputation: 21209
Since you are using native DOM, it bypasses angular's processors. You need to call scope.$digest() after changing angular's state to tell it that something changed.
droppableElt.addEventListener(
'drop',
function (e) {
if (e.stopPropagation) e.stopPropagation();
this.classList.remove('over');
let item = document.getElementById(e.dataTransfer.getData('Text'));
this.appendChild(item);
item.id = '';
scope.treeJson = parseTreeToDOM(elt[0].children[0]);
scope.$digest();
},
false
);
Upvotes: 1