使用JavaScript(Angular)中的foreach循环填充数组

3

我有许多分类,每个分类又包含很多项。现在我从API返回了一个分类列表和一个项列表。

现在我希望在Angular中将它们合并成一个对象。我已经按照以下步骤进行操作:

        if ($scope.categories_norm) {
            $scope.delivery_items = [];

            //get categories
            angular.forEach(data.item_categories.normal_categories, function (v, k) {
                //push categories
                $scope.delivery_items.push(v);

                //push items for categories
                var i = 0;
                if ($scope.items) {
                    angular.forEach($scope.items, function (val, key) {
                        i++;
                        if (val.item_category_id == v.item_category_id) {
                        //console.log();
                            $scope.delivery_items[k][i].push(val);
                        }
                    });
                }
            });
        }

由于某些原因,我无法填充它。它返回错误:TypeError: Cannot read property 'push' of undefined。

我该如何正确操作?我想在每个类别对象内部使用一个包含所有项目的对象。


它在哪一行出错了? - Thermatix
$scope.delivery_items[k][i].push(val); - Reza
2个回答

0

移除 '[i]'

    if ($scope.categories_norm) {
        $scope.delivery_items = [];

        //get categories
        angular.forEach(data.item_categories.normal_categories, function (v, k) {
            //push categories
            $scope.delivery_items.push(v);

            //push items for categories
            var i = 0;
            if ($scope.items) {
                angular.forEach($scope.items, function (val, key) {
                    i++;
                    if (val.item_category_id == v.item_category_id) {
                    //console.log();
                        $scope.delivery_items[k].push(val);
                    }
                });
            }
        });
    }

或者移除 'push':

    if ($scope.categories_norm) {
        $scope.delivery_items = [];

        //get categories
        angular.forEach(data.item_categories.normal_categories, function (v, k) {
            //push categories
            $scope.delivery_items.push(v);

            //push items for categories
            var i = 0;
            if ($scope.items) {
                angular.forEach($scope.items, function (val, key) {
                    i++;
                    if (val.item_category_id == v.item_category_id) {
                    //console.log();
                        $scope.delivery_items[k][i] = val;
                    }
                });
            }
        });
    }

当我去掉push时,“a”已经完成了两者,此时出现“TypeError: Cannot set property '9' of undefined”错误。而当我不使用push时,却出现“TypeError: undefined is not a function”错误。 - Reza

0

我认为问题出在$scope.delivery_items[k][i].push(val);中的k,将其改为v并查看结果。

编辑:

好的,在重新查看了您的问题后,我认为这个方法可能更好:

if ($scope.categories_norm) {
        $scope.delivery_items = {}; // create empty object
        //get categories
        angular.forEach(data.item_categories.normal_categories, function (v, k) {
            var catagery = v.category_name; // create cataogry variable scoped to this block
            $scope.delivery_items[category] = {}; //create empty category object using category name as the key
            if ($scope.items) {
                angular.forEach($scope.items.filter(check_item_category(v.item_category_id)), function (val, key) {
                    $scope.delivery_items[category][category_info] = v; // comment out or omit this line if you don't want category information included within the category
                    $scope.delivery_items[category][val.item_name] = val; // set item object to it's corosponding name
            });
        };
    });
}

function check_item_category (category_id) {
    return function(item) {
        return item.item_category_id == category_id
    }
}

你仍然需要填写其中的一些部分(即如何获取类别和项目名称),但那应该是你想要的。

编辑:我切换到使用过滤器,我只是不喜欢为每个项目看到id检查,我认为使用过滤器会更清洁。

编辑:

它应该最终呈现出这样一个对象:

{
    "category_1" : {
        "category_info" : category_object,
        "item_1" : item_1_object,
        "item_2" : item_2_object
    }
    "category_2" : {
        "category_info" : category_object,
        "item_1" : item_1_object,
        "item_2" : item_2_object,
        "item_3" : item_3_object,
    }
    "category_3" : {
        "category_info" : category_object,
        "item_1" : item_1_object,
        "item_2" : item_2_object,
        "item_3" : item_3_object,
    }
}

编辑: 好的,最后一次,我再看了一遍发现这可以更快(减少对$scope.items迭代的次数),同时还将消除数据重复(项目名称在关键字和项对象中都存在)。

但请注意,如果使用此解决方案,您不会将类别对象与类别一起存储。

if ($scope.categories_norm) {
        $scope.delivery_items = get_items_sorted_by_category(data.item_categories.normal_categories,$scope.items) // create empty object
    });
}

function get_items_sorted_by_category(categories,items) {
    var filled_object = {}
    for(var category in categories){
        //will need to change how you set the catagory name as I don't know how this object looks
        filled_object[category.name] = items.filter(check_item_category(category.item_category_id)) // will filter out any objects that don't have the correct caragory ID
    };
    return filled_object;
}

function check_item_category (category_id) {
    return function(item) {
        return item.item_category_id == category_id
    }
}

你应该得到一个看起来像这样的对象:

{
    "category_1" : [
        "item_1", 
        "item_2", 
        "item_3"
    ]
    "category_2" : [
        "item_1",
        "item_2",
        "item_3"
    ]
    "category_3" : [        
        "item_1",
        "item_2",
        "item_3"
    ]
}

类型错误:无法读取未定义的属性'1'.. 在那一行 - Reza
我不理解这个解决方案。项目也是带有多个数据的对象。 - Reza
以前你使用的数组方式有点奇葩,看起来不太对劲。现在这种方式可以创建一个有组织的对象;以类别名称作为对象的键,然后将条目名称作为对象键填充到包含该条目信息的对象中。请参考答案中的示例对象。 - Thermatix
现在我得到了这个错误:ReferenceError: item_category_id未定义,您的代码在此行上:angular.forEach($scope.items.filter(check_item_catagory(item_category_id,v.item_category_id)), function (val, key) { - Reza
对不起,我犯了一个错误,过滤器是个棘手的问题。为了让回调函数接受额外的值(类别ID),您需要创建一个函数,该函数接受一个值(类别ID),然后返回实际的回调函数,该回调函数还接受一个值(数组中的项),然后将该项的ID与之前提供的类别ID进行比较。 - Thermatix

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接