Nested/embedded ngRepeats 中的 $resources
Nested/embedded $resources in ngRepeats
我的 API 填充了一些嵌套模型。使用购物示例,当您查询 orders
时,items
属性 会填充 description
和 quantity
而不是仅返回商品 ID。
orders: [
{_id: 1,
items: [
{_id: 100,
description: "apple", // from lookup in the Items table
quantity: 4 // from lookup in the Items table
}, ...
],
...
}, ...
]
我的观点是这样的:
<div ng-repeat="order in vm.orders">
<ul ng-repeat="item in order.items">
<li ng-model="vm.orders[$parent.$index].items[$index].description" ng-blur="item.$update()"></li>
<li ng-model="vm.orders[$parent.$index].items[$index].quantity" ng-blur="item.$update()"></li>
</ul>
</div>
目标是让用户从此视图更新项目描述和数量。 (li
是 contenteditable 指令。)update
调用应该在 Item
$resource
上进行,而不是 Order
$resource
。
有没有办法让 Angular 识别出嵌入的文档是 Item
s,我可以根据它调用 $update
之类的方法?
我的解决方法是更改 ng-blur
以调用等效于此的控制器方法:
ng-blur="Item.update({_id: item._id})"
(如果我这样做,那么使用 $parent.$index
和 $index
语法也没有意义——只需 order.item
和 item.description
。)
您要做的是将嵌套资源转换为实际资源。为此,请将响应转换器添加到您的 Order
资源。例如
.factory('Order', function($resource, $http, Item) {
var responseTransformer = function(order) {
order.items = order.items.map(function(item) {
return new Item(item);
});
return order;
};
// somewhat lifted from https://docs.angularjs.org/api/ng/service/$http#overriding-the-default-transformations-per-request
var appendResponseTransformer = function(transformer) {
var defaults = $http.defaults.transformResponse;
defaults = angular.isArray(defaults) ? defaults : [defaults];
return defaults.concat(transform);
};
return $resource('/orders', whatever, {
get: {
method: 'GET',
url: '/orders/:id',
params: { id: '@id' },
transformResponse: appendResponseTransform(responseTransformer)
},
query: {
method: 'GET',
isArray: true,
transformResponse: appendResponseTransform(function(orders) {
return orders.map(responseTransformer);
})
}
});
});
替代方法是只处理控制器中的 item
更新。例如
ng-blur="updateItem(item)"
和
$scope.updateItem = function(item) {
Item.update(item);
};
我的 API 填充了一些嵌套模型。使用购物示例,当您查询 orders
时,items
属性 会填充 description
和 quantity
而不是仅返回商品 ID。
orders: [
{_id: 1,
items: [
{_id: 100,
description: "apple", // from lookup in the Items table
quantity: 4 // from lookup in the Items table
}, ...
],
...
}, ...
]
我的观点是这样的:
<div ng-repeat="order in vm.orders">
<ul ng-repeat="item in order.items">
<li ng-model="vm.orders[$parent.$index].items[$index].description" ng-blur="item.$update()"></li>
<li ng-model="vm.orders[$parent.$index].items[$index].quantity" ng-blur="item.$update()"></li>
</ul>
</div>
目标是让用户从此视图更新项目描述和数量。 (li
是 contenteditable 指令。)update
调用应该在 Item
$resource
上进行,而不是 Order
$resource
。
有没有办法让 Angular 识别出嵌入的文档是 Item
s,我可以根据它调用 $update
之类的方法?
我的解决方法是更改 ng-blur
以调用等效于此的控制器方法:
ng-blur="Item.update({_id: item._id})"
(如果我这样做,那么使用 $parent.$index
和 $index
语法也没有意义——只需 order.item
和 item.description
。)
您要做的是将嵌套资源转换为实际资源。为此,请将响应转换器添加到您的 Order
资源。例如
.factory('Order', function($resource, $http, Item) {
var responseTransformer = function(order) {
order.items = order.items.map(function(item) {
return new Item(item);
});
return order;
};
// somewhat lifted from https://docs.angularjs.org/api/ng/service/$http#overriding-the-default-transformations-per-request
var appendResponseTransformer = function(transformer) {
var defaults = $http.defaults.transformResponse;
defaults = angular.isArray(defaults) ? defaults : [defaults];
return defaults.concat(transform);
};
return $resource('/orders', whatever, {
get: {
method: 'GET',
url: '/orders/:id',
params: { id: '@id' },
transformResponse: appendResponseTransform(responseTransformer)
},
query: {
method: 'GET',
isArray: true,
transformResponse: appendResponseTransform(function(orders) {
return orders.map(responseTransformer);
})
}
});
});
替代方法是只处理控制器中的 item
更新。例如
ng-blur="updateItem(item)"
和
$scope.updateItem = function(item) {
Item.update(item);
};