1

我使用这个脚本作为我的起点:http: //jsfiddle.net/EJGHX/ 我已经修改它以从数据库构建一个列表,但我无法以服务器可以读取的格式将其发送回。

这是我的代码:

JS

var app = angular.module('app', []);

app.config(function ($routeProvider) {
    $routeProvider.when('/article/:slug', {
        templateUrl: '/university_assets/partials/admin/content.html',
        controller: 'TreeController'
    })
        .when('/', {
        templateUrl: '/university_assets/partials/home.html'
    })
        .when('/add', {
        templateUrl: '/university_assets/partials/admin/addContent.html'
    })
        .otherwise({
        templateUrl: '/university_assets/partials/404.html'
    });
});

app.directive('yaTree', function () {

    return {
        restrict: 'A',
        transclude: 'element',
        priority: 1000,
        terminal: true,
        compile: function (tElement, tAttrs, transclude) {

            var repeatExpr, childExpr, rootExpr, childrenExpr;

            repeatExpr = tAttrs.yaTree.match(/^(.*) in ((?:.*\.)?(.*)) at (.*)$/);
            childExpr = repeatExpr[1];
            rootExpr = repeatExpr[2];
            childrenExpr = repeatExpr[3];
            branchExpr = repeatExpr[4];

            return function link(scope, element, attrs) {

                var rootElement = element[0].parentNode,
                    cache = [];

                // Reverse lookup object to avoid re-rendering elements
                function lookup(child) {
                    var i = cache.length;
                    while (i--) {
                        if (cache[i].scope[childExpr] === child) {
                            return cache.splice(i, 1)[0];
                        }
                    }
                }

                scope.$watch(rootExpr, function (root) {

                    var currentCache = [];

                    // Recurse the data structure
                    (function walk(children, parentNode, parentScope, depth) {

                        var i = 0,
                            n = children.length,
                            last = n - 1,
                            cursor,
                            child,
                            cached,
                            childScope,
                            grandchildren;

                        // Iterate the children at the current level
                        for (; i < n; ++i) {

                            // We will compare the cached element to the element in 
                            // at the destination index. If it does not match, then 
                            // the cached element is being moved into this position.
                            cursor = parentNode.childNodes[i];

                            child = children[i];

                            // See if this child has been previously rendered
                            // using a reverse lookup by object reference
                            cached = lookup(child);

                            // If the parentScope no longer matches, we've moved.
                            // We'll have to transclude again so that scopes 
                            // and controllers are properly inherited
                            if (cached && cached.parentScope !== parentScope) {
                                cache.push(cached);
                                cached = null;
                            }

                            // If it has not, render a new element and prepare its scope
                            // We also cache a reference to its branch node which will
                            // be used as the parentNode in the next level of recursion
                            if (!cached) {
                                transclude(parentScope.$new(), function (clone, childScope) {

                                    childScope[childExpr] = child;

                                    cached = {
                                        scope: childScope,
                                        parentScope: parentScope,
                                        element: clone[0],
                                        branch: clone.find(branchExpr)[0]
                                    };

                                    // This had to happen during transclusion so inherited 
                                    // controllers, among other things, work properly
                                    parentNode.insertBefore(cached.element, cursor);

                                });
                            } else if (cached.element !== cursor) {
                                parentNode.insertBefore(cached.element, cursor);
                            }

                            // Lets's set some scope values
                            childScope = cached.scope;

                            // Store the current depth on the scope in case you want 
                            // to use it (for good or evil, no judgment).
                            childScope.$depth = depth;

                            // Emulate some ng-repeat values
                            childScope.$index = i;
                            childScope.$first = (i === 0);
                            childScope.$last = (i === last);
                            childScope.$middle = !(childScope.$first || childScope.$last);

                            // Push the object onto the new cache which will replace
                            // the old cache at the end of the walk.
                            currentCache.push(cached);

                            // If the child has children of its own, recurse 'em.             
                            grandchildren = child[childrenExpr];
                            if (grandchildren && grandchildren.length) {
                                walk(grandchildren, cached.branch, childScope, depth + 1);
                            }
                        }
                    })(root, rootElement, scope, 0);

                    // Cleanup objects which have been removed.
                    // Remove DOM elements and destroy scopes to prevent memory leaks.
                    i = cache.length;

                    while (i--) {
                        cached = cache[i];
                        if (cached.scope) {
                            cached.scope.$destroy();
                        }
                        if (cached.element) {
                            cached.element.parentNode.removeChild(cached.element);
                        }
                    }

                    // Replace previous cache.
                    cache = currentCache;

                }, true);
            };
        }
    };
});


app.controller('TreeController', function ($rootScope, $scope, $timeout, $http, $location) {

    $scope.data = {
        children: [{
            text: '',
            children: []
        }]
    };
    $http.get('/university/list').success(function (data) {
        var myArr = data;
        for (var i = 0; i < myArr.length; i++) {
            myArr[i].children = [];
            for (var q = 0; q < myArr.length; q++) {
                if (myArr[i].id == myArr[q].parentid) {
                    var temp = {
                        id: myArr[q].id,
                        text: myArr[q].text,
                        index: myArr[q].index
                    };
                    myArr[i].children.push(temp);
                };
            };

        };
        $scope.data = ({
            children: myArr
        });
    });
    $scope.index = function (i, child) {
        child.index = i;
    }

    $http.get('/university' + $location.path()).success(function (data) {
        $rootScope.pageContent = data[0];
        $rootScope.page = $scope.pageContent;
    });
    $scope.edit = function (child) {
        $http.get('/university/article/' + child.id).success(function (data) {
            $rootScope.pageContent = data[0];
            $rootScope.page = $scope.pageContent;
        });
        $location.path('/article/' + child.id);
        $("#article").attr("action", "/admin/updateArticle");
        $('.admin-actions button').text(' Update ');
    };
    $scope.toggleMinimized = function (child) {
        child.minimized = !child.minimized;
    };

    $scope.addChild = function (child) {
        child.children.push({
            title: '',
            children: []
        });
    };

    $scope.remove = function (child) {
        function walk(target) {
            var children = target.children,
                i;
            if (children) {
                i = children.length;
                while (i--) {
                    if (children[i] === child) {
                        return children.splice(i, 1);
                    } else {
                        walk(children[i])
                    }
                }
            }
        }
        walk($scope.data);
    }

    $scope.update = function (event, ui) {
        var root = event.target,
            item = ui.item,
            parent = item.parent(),
            target = (parent[0] === root) ? $scope.data : parent.scope().child,
            child = item.scope().child,
            index = item.index();

        target.children || (target.children = []);

        function walk(target, child) {
            var children = target.children,
                i;
            if (children) {
                i = children.length;
                while (i--) {
                    if (children[i] === child) {
                        return children.splice(i, 1);
                    } else {
                        walk(children[i], child);
                    }
                }
            }
        }
        walk($scope.data, child);

        target.children.splice(index, 0, child);

            var graph = $scope.data.children;
            console.log(graph);
            var i, l,
            nodes=[],
            visited=[];

            function clone(n) {
             // improve the function yourself I'm lazy
             return {
                "id": n.id,
                "parentid": n.parentid,
                "text": n.text,
                "index": n.index
             };
            }

            function helper (node) {
                var i, limit;
                if (visited.indexOf(node.id) == -1) {
                  visited.push(node.id);
                  nodes.push(clone(node));
                  if( node.children)
                  for (i=0, limit = node.children.length; i< limit; i++) {
                    helper(node.children[i]);
                  }
                }
            }

            for (i=0, l = graph.length; i< l; i++) {
                helper(graph[i]);
            }

            nodes = JSON.stringify(nodes);
            $http.post('/admin/sort/', nodes).success(function () {});        
    };

});


app.directive('uiNestedSortable', ['$parse', function ($parse) {

    'use strict';

    var eventTypes = 'Create Start Sort Change BeforeStop Stop Update Receive Remove Over Out Activate Deactivate'.split(' ');

    return {
        restrict: 'A',
        link: function (scope, element, attrs) {

            var options = attrs.uiNestedSortable ? $parse(attrs.uiNestedSortable)() : {};

            angular.forEach(eventTypes, function (eventType) {

                var attr = attrs['uiNestedSortable' + eventType],
                    callback;

                if (attr) {
                    callback = $parse(attr);
                    options[eventType.charAt(0).toLowerCase() + eventType.substr(1)] = function (event, ui) {
                        scope.$apply(function () {

                            callback(scope, {
                                $event: event,
                                $ui: ui
                            });
                        });
                    };
                }

            });

            element.nestedSortable(options);

        }
    };
}]);

除了一些添加的 $http 请求和这个之外,它基本上是相同的:

    var graph = data.children;
    console.log(graph);
    var i, l,
    nodes=[],
    visited=[];

    function clone(n) {
     // improve the function yourself I'm lazy
     return {
        "id": n.id,
        "parentid": n.parentid,
        "text": n.text,
        "index": n.index
     };
    }

    function helper (node) {
        var i, limit;
        if (visited.indexOf(node.id) == -1) {
          visited.push(node.id);
          nodes.push(clone(node));
          if( node.children)
          for (i=0, limit = node.children.length; i< limit; i++) {
            helper(node.children[i]);
          }
        }
    }

    for (i=0, l = graph.length; i< l; i++) {
        helper(graph[i]);
    }

    nodes = JSON.stringify(nodes);
    $http.post('/admin/sort/', nodes).success(function () {});  

我需要在更新功能运行后运行它。这会展平我的 $scope.data 数组并将其发送到服务器。

我的问题是..如果我把上面的函数放在我的 $scope.update 函数中,它会在更改之前发送以前的数据。它会发送 'index': 1,当我把它移到 'index': 2 时。

4

1 回答 1

0

我使用 angulars 'copy' 方法来防止修改范围,并且我使用 javascript 来定义索引而不是这里看到的 angular: var data = angular.copy(target);

    for (i=0, l=data.length; i<l; i++){
        parentid = data[i].id;
        data[i]['index'] = i;
        if(data[i].children) {
            if(data[i].children.length > 0){
                for (q=0, r=data[i].children.length; q<r; q++){
                    data[i].children[q]['parentid'] = parentid;
                    data[i].children[q]['index'] = q;
                }
            }
        }
    }
于 2013-04-15T19:06:20.590 回答