【问题标题】:Add a child dynamically within a nested array with Angulajs使用 Angularjs 在嵌套数组中动态添加子项
【发布时间】:2015-08-28 20:33:45
【问题描述】:

我在 angularjs 中有一个数组

$scope.structure =
{
  folders:  [
              { name: 'Folder 1', files: [{ name: 'File 1.jpg' }, { name: 'File 2.png' }], folders:
                      [
                        { name: 'Subfolder 1', files: [{ name: 'Subfile 1.txt' }], folders:[] },
                        { name: 'Subfolder 2', files:[], folders:[] },
                        { name: 'Subfolder 3', files:[], folders:[] }
                    ]},
              { name: 'Folder 2', files:[], folders:[] }
            ],
  files:    [
              { name: 'File 1.gif' },
              { name: 'File 2.gif' }
            ]
};

结构如下:

Root
--Folder 1
----Subfolder 1
------Subfile 1.txt
----Subfolder 2
----Subfolder 3
----File 1.jpg
----File 2.png
--Folder 2
--File 1.gif
--File 2.gif

现在我想在现有文件夹中添加其他文件夹和文件,例如现有文件夹“子文件夹 2”下的文件夹“新建文件夹”。

Root
--Folder 1
----Subfolder 1
------Subfile 1.txt
----Subfolder 2
------New Folder
----Subfolder 3
----File 1.jpg
----File 2.png
--Folder 2
--File 1.gif
--File 2.gif

我可以使用以下功能手动完成:

$scope.structure.folders[0].folders[1].folders.push({ name: 'New Folder', files:[], folders:[] });

但现在我想动态地执行此操作,只需提供我要添加的文件夹的名称即可。我想我必须迭代孔数组并搜索名称。

但是如何确定数组中的适当位置以在之后添加文件夹?

如果有人可以帮助我,那就太好了!

非常感谢!

尼哥

【问题讨论】:

标签: javascript arrays angularjs nested


【解决方案1】:

问题在于它是一个嵌套列表,并且一个父级与其子级相似,那么这些子级是其子级的父级......这可以深入。

我建议这个库:https://github.com/wix/angular-tree-control

如果你喜欢 Vanilla JS,你可以编写一个递归函数来迭代文件夹中的文件夹并执行你需要的任何操作:) 下面是一个展示递归的简单示例。

https://jsfiddle.net/su42vb56/1/

var tree = {
    name: 'A', 
    folders: [
        {
            name: 'B',
            folders: []
        },
        {
            name: 'C',
            folders: []
        }
    ]
};

function findFolder(folder, name) {
    var i;
    var match;

    if(folder.name === name) {
        return folder;
    } else {
        for(i = 0; i < folder.folders.length; i++) {
            match = findFolder(folder.folders[i], name);
            if(match) {
                return folder.folders[i];
            }
        }
    }
}

findFolder(tree, 'C').folders.push({name: 'newFolder', folders: []});
console.log(tree); // There is a newFolder under C.

【讨论】:

    【解决方案2】:

    我尝试动态设置对象。但是我目前找不到添加的最佳方法。坦率地说,我喜欢你的问题。我试图找到。

    /**
     * Created by sherali on 8/30/15.
     */
    var Helper = {
            isEmpty: function (obj) {
                return !obj || obj === null || obj === undefined || Array.isArray(obj) && obj.length === 0;
            },
            clearArray: function (arr) {
                if (arr && Array.isArray(arr)) {
                    arr.length = 0;
                }
            },
            pushArray: function (arr1, arr2) {
                if (arr1 && arr2 && Array.isArray(arr1)) {
                    arr1.push.apply(arr1, Array.isArray(arr2) ? arr2 : [arr2]);
                }
            },
            setArray: function (arr1, arr2) {
                this.clearArray(arr1);
                this.pushArray(arr1, arr2);
            }
        };
        
        function FileOrFolder(name, folderArray, fileArray, format, isFile, size) {
            var _name,
                _folders = [],
                _files = [],
                _size = 0,
                _format = null,
                _isFile = false,
                _json = {};
            var self = this;
            Object.defineProperties(this, {
                name: {
                    get: function () {
                        return _name;
                    },
                    set: function (val) {
                        _name = val;
                    },
                    enumerable: true
                },
                folders: {
                    get: function () {
                        return _folders;
                    },
                    set: function (val) {
                        Helper.setArray(_folders, val);
                    },
                    enumerable: true
                },
                files: {
                    get: function () {
                        return _files;
                    },
                    set: function (val) {
                        Helper.setArray(_files, val);
                    },
                    enumerable: true
                },
                size: {
                    get: function () {
                        return _size;
                    },
                    set: function (val) {
                        _size = Helper.isEmpty(val) ? 0 : val;
                    },
                    enumerable: true
                },
                format: {
                    get: function () {
                        return _format;
                    },
                    set: function (val) {
                        _format = val;
                    },
                    enumerable: true
                },
                isFile: {
                    get: function () {
                        return _isFile;
                    },
                    set: function (val) {
                        _isFile = val;
                    },
                    enumerable: true
                },
                json: {
                    get: function () {
                        return _json;
                    },
                    set: function (val) {
                        _json = val;
                    },
                    enumerable: true
                }
            });
            this.addFileOrFolder = function (item, isFile) {
                Object.keys(item.json).forEach(function (key, i, obj) {
                    if (isFile) {
                        Helper.pushArray(_files, item);
                        _json[name].files[key] = item.json[key];
                    } else {
                        Helper.pushArray(_folders, item);
                        _json[name].folders[key] = item.json[key];
                    }
                });
            };
            if (!Helper.isEmpty(name)) {
                this.name = name;
                _json[name] = {folders: {}, files: {}, size: 0, format: undefined};
        
                if (!Helper.isEmpty(folderArray)) {
                    this.folders = folderArray;
                    _folders.forEach(function (item, index, array) {
                        Object.keys(item.json).forEach(function (key, i, obj) {
                            _json[name].folders[key] = item.json[key];
                        });
                    });
                }
                if (!Helper.isEmpty(fileArray)) {
                    this.files = fileArray;
                    _files.forEach(function (item, index, array) {
                        Object.keys(item.json).forEach(function (key, i, obj) {
                            _json[name].files[key] = item.json[key];
                        });
                    });
                }
                this.size = size;
                _json[name]["size"] = _size;
        
                if (isFile) {
                    this.isFile = isFile;
                }
                _json[name]["isFile"] = _isFile;
                this.format = format;
                _json[name]["format"] = _format;
            }
        }
        
        
        var root = new FileOrFolder("root",
            [
                new FileOrFolder("Folder1", [
                    new FileOrFolder("folder1.1", [
                        new FileOrFolder("folder1.1.1", [
                            new FileOrFolder("folder1.1.1.1")
                        ])
                    ]),
                    new FileOrFolder("folder1.2", [
                        new FileOrFolder("folder1.2.1", [
                            new FileOrFolder("folder1.2.1.1")
                        ])
                    ])
                ]),
                new FileOrFolder("Folder2", [new FileOrFolder("folder2.1")], [new FileOrFolder("file", null, null, ".bat", true)])
            ]);
        
        root.addFileOrFolder(new FileOrFolder("Folder3", null, [
            new FileOrFolder("file3.1", null, null, ".txt", true),
            new FileOrFolder("file3.2", null, null, ".txt", true),
            new FileOrFolder("file3.3", null, null, ".txt", true)
        ]));
        console.log("files of root : ", root.folders[0].folders);
        console.log("folder 1.1", root.json.root.folders["Folder1"].folders["folder1.1"]);

    【讨论】:

    • 感谢您的回答。我读了它。它已经工作了吗?
    • 您只需复制并粘贴到控制台。确实如此。但是某些子项内部没有添加方法(您只能通过root添加)。除了迭代之外,我应该找到最佳方法。
    猜你喜欢
    • 2023-03-14
    • 2020-04-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-17
    • 2013-01-13
    • 1970-01-01
    • 2022-01-13
    • 2018-04-22
    相关资源
    最近更新 更多