javascript - 在 Angular 中的指令和 Controller 之间传递数据

标签 javascript angularjs json

我正在 Angular 1 中开发一个项目。任务是从 json 对象创建 DOM 树,并通过 native 拖放 DOM 操作对其进行操作(不使用 jQuery 等)。我已经完成了解析 json-> dom 函数、从服务器加载 json、一些拖放事件处理程序。现在我的问题是当我完成 DROP 事件时如何更新 json 对象(从这个对象我得到一个 ul>li 树结构)。 现在,代码

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
                );
            });
        }
    }
}

因此,在 Sup 指令中,当创建 drop 事件时,我重新初始化 treeJson 变量,之后我需要在主指令中重新初始化树,并在 Controller 中获取来自该变量的新 json 结构,因为使用了 $watch,但它没有发生。

请帮忙

感谢您的关注:)

附注Here it is in Plnkr.co

最佳答案

由于您使用的是 native DOM,它会绕过 Angular 的处理器。您需要调用scope.$digest()改变 Angular 的状态后告诉它发生了变化。

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
);

关于javascript - 在 Angular 中的指令和 Controller 之间传递数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40263853/

相关文章:

javascript - 我如何从选项卡展开(切换)开始?

asp.net-mvc - AngularJS $routeProvider 和 ASP.NET MVC 中的相对 URL

python - json与python中另一个json的递归比较

javascript - 在循环中构建数组后发送后无法设置 header

javascript - 在 mouseenter 上使用 javascript 连续循环 div 上的颜色

javascript - 如何通过点分隔路径动态分配 ngmodel

javascript - 为什么我得到未定义

ruby-on-rails - 如何将所有RoR模型的include_root_in_json设置为false?

Android JSONObject 在创建时跳过空值

javascript - 荒谬的 JavaScript 错误 : have to call a function multiple times for it to behave correctly