我一直在玩Angular并遇到嵌套JSON的障碍。
此演示应用程序适用于销售目录。每个Catalog
都会包含一个CatalogItemCategory
数组,每个类别都会有一个CatalogItem
数组。所有这些都是$resource
个对象。
后端以嵌套的JSON响应进行响应(如下所示)。 是否存在将其映射到客户端的“角度方式”?
理想情况下,我更愿意将客户端模型保留为,
$scope.catalog = {};
$scope.catalog.catalogItemCategories = [];
$scope.catalog.catalogItemCategories[categoryIndex].catalogItems = [];
我已经花了几个小时,我能想到的两个解决方案是,
显然,第一种方法需要大量的JSON响应维护工作,第二种方法需要许多JSON调用。有最佳方法吗?
{
id:1,
tenant_id:2,
business_id:1,
catalog_group_id:1,
name:"Catalog 1",
deleted_at:null,
created_at:"2014-06-14 12:34:05",
updated_at:"2014-06-14 12:34:05",
catalog_item_categories:[
{
id:3,
tenant_id:2,
business_id:1,
catalog_id:1,
name:"Services category 2",
deleted_at:null,
created_at:"2014-06-14 12:34:05",
updated_at:"2014-06-14 12:34:05",
catalog_items:[
{
id:3,
tenant_id:2,
business_id:2,
catalog_item_category_id:3,
quantity:null,
price:"0.00",
price_option:null,
name:"CatalogItem 3",
deleted_at:null,
created_at:"2014-06-14 12:34:05",
updated_at:"2014-06-14 12:34:05"
},
{
id:4,
tenant_id:2,
business_id:2,
catalog_item_category_id:3,
quantity:null,
price:"0.00",
price_option:null,
name:"CatalogItem 4",
deleted_at:null,
created_at:"2014-06-14 12:34:05",
updated_at:"2014-06-14 12:34:05"
}
]
},
{
id:4,
tenant_id:2,
business_id:1,
catalog_id:1,
name:"Products categorys 2",
deleted_at:null,
created_at:"2014-06-14 12:34:05",
updated_at:"2014-06-14 12:34:05",
catalog_items:[
]
}
]
}
修改
经过几个小时后,我得到了一个解决方案。我们的想法是将模型列表作为数组传递,然后根据JSON中的树级动态构建正确的模型。明显的缺点是如果JSON的嵌套级别发生变化,这将无效。
在下面发布我的测试解决方案。
function processObject(data, currentLevel, modelList) {
var customResponse = {};
angular.forEach(data, function(value, key) {
if (angular.isArray(value)) {
var arrayName = stringToCamelCase(key);
var nextLevel = currentLevel + 1;
var parsedArray = processArray(value, nextLevel, modelList);
if (parsedArray.length) {
customResponse[arrayName] = parsedArray;
}
} else {
customResponse[key] = value;
}
});
var newobject = new modelList[currentLevel](customResponse);
return newobject;
}
function processArray(data, currentLevel, modelList){
var customResponse = [];
angular.forEach(data, function(value) {
customResponse.push(processObject(value, currentLevel, modelList));
});
return customResponse;
}
demoApp.controller('CatalogIndexController', function($scope, $http, BusinessService, $routeParams, Catalog, CatalogItemCategory, CatalogItem) {
// setup defaults
$scope.catalog = {};
// load default catalog data
$http.get('/business/' + $routeParams.businessId + '/catalogs/default')
.success(function(data) {
// 3rd argument - pass the nest structure as an array
$scope.catalog = processObject(data, 0, [Catalog, CatalogItemCategory, CatalogItem]);
console.log($scope.catalog);
});
$scope.save = function(item) {
item.$save();
};
});
function processObject(data, currentLevel, modelList) {
var customResponse = {};
angular.forEach(data, function(value, key) {
if (angular.isArray(value)) {
var arrayName = stringToCamelCase(key);
var nextLevel = currentLevel + 1;
var parsedArray = processArray(value, nextLevel, modelList);
if (parsedArray.length) {
customResponse[arrayName] = parsedArray;
}
} else {
customResponse[key] = value;
}
});
var newobject = new modelList[currentLevel](customResponse);
return newobject;
}
function processArray(data, currentLevel, modelList){
var customResponse = [];
angular.forEach(data, function(value) {
customResponse.push(processObject(value, currentLevel, modelList));
});
return customResponse;
}
demoApp.controller('CatalogIndexController', function($scope, $http, BusinessService, $routeParams, Catalog, CatalogItemCategory, CatalogItem) {
// setup defaults
$scope.catalog = {};
// load default catalog data
$http.get('/business/' + $routeParams.businessId + '/catalogs/default')
.success(function(data) {
// 3rd argument - pass the nest structure as an array
$scope.catalog = processObject(data, 0, [Catalog, CatalogItemCategory, CatalogItem]);
console.log($scope.catalog);
});
$scope.save = function(item) {
item.$save();
};
});