1

我正在尝试使用 JavaScript 构建层次结构(树结构)。为此,我编写了一个Node代表树中节点的类。当我从数据库中检索数据时,所有数据都被正确检索(即:根节点具有ParentIdas null,它有 3 个子节点指向它作为父节点,并且后代节点也已正确设置...... )。但是当我尝试将它们映射到我的 JavaScript 模型时,Children根节点的属性最终变为undefined. 我不知道这怎么可能,即使在运行时,当我Children在控制台中输出属性的内容时,我可以看到子节点被添加到其中。这是我的代码:

var Node = function (obj) {
    var self = this;
    var isDefined = obj != undefined;

    self.hasChildren = function () {
        return self.Children.length > 0;
    };

    self.hasParent = function () {
        var p = self.ParentId;
        return !(p == null || p == undefined || p == 0);
    };

    self.addChildren = function (objArray) {
        if (!$.isArray(self.Children)) {
            self.Children = [];
        }
        for (var i = 0; i < objArray.length; i++) {
            self.addChild(objArray[i]);
        }
    };

    self.addChild = function (obj) {
        if (obj instanceof Node) {
            self.Children.push(obj);
        } else {
            var n = new Node(obj);
            self.Children.push(n);
        }
    };

    self.removeChild = function (n) {
        var index = self.Children.indexOf(n);
        if (index > -1) {
            self.Children.splice(index, 1);
        }
    };

    self.Id = isDefined ? obj.Id : null;
    self.ParentId = isDefined ? obj.ParentId : null;
    self.Name = isDefined ? obj.Name : '';
    self.Children = isDefined ? self.addChildren(obj.Children) : [];
    self.TypeId = isDefined ? obj.TypeId : null;
};

我考虑该addChildren方法的方式是,我会将来自服务器的原始 JSON 对象传递给对象的构造函数Node,然后如果它有任何子对象(本质上与父对象具有相同的属性),addChildren将被调用这反过来Node将为每个元素创建一个新元素。最终,树将​​递归构建。

那么我哪里做错了?为什么Children财产最终是undefined

4

1 回答 1

2
self.Children = isDefined ? self.addChildren(obj.Children) : [];

您正在设置 self.Children 等于self.addChildren(). 该功能没有回报。

这是我推荐的几件事

function Node(obj) {
    // clean constructor moving function definitions to prototype
    var self = this;

    // ensure that we at least have an object passed in
    obj = obj || {};

    // default values at the top
    self.Id = null;
    self.ParentId = null;
    self.Name = '';
    self.Children = [];
    self.TypeId = null;

    // fold in data with $.extend, no need to specify each key manually
    // third object is to overwrite any added Children as those need to be handled seperately
    $.extend(self, obj, { Children : [] });

    // if we have children, add them using the addChildren method
    if (typeof obj.Children !== undefined && $.isArray(obj.Children)) {
        self.addChildren(obj.Children);
    }
}

// using prototype to reduce memory footprint
Node.prototype.hasChildren = function () {
    return this.Children.length > 0;
};

Node.prototype.hasParent = function () {
    var p = this.ParentId;
    return !(p == null || p == undefined || p == 0);
};

Node.prototype.addChildren = function (objArray) {
    for (var i = 0; i < objArray.length; i++) {
        this.addChild(objArray[i]);
    }
};

Node.prototype.addChild = function (obj) {
    if (obj instanceof Node) {
        this.Children.push(obj);
    } else {
        var n = new Node(obj);
        this.Children.push(n);
    }
};

Node.prototype.removeChild = function (n) {
    var index = this.Children.indexOf(n);
    if (index > -1) {
        this.Children.splice(index, 1);
    }
};

然后我可以像这样使用它:

test = new Node({ Id : "Something", Children : [{ Id : "Interior", Children : [] }] })

使用原型可以减少内存占用,并且不会为您创建的每个内部函数创建函数引用Node。每个人仍然会通过一个变量Node引用它的内部数据。this

于 2013-02-28T07:37:47.767 回答