Перебор ресурса AngularJS с вложенными массивами
У меня есть небольшое веб-приложение, которое использует AngularJS на внешнем интерфейсе и Java на заднем. Я использую REST для общения.
На сервере я создаю список списков, например:
List<List<Data>> allData = new ArrayList<>();
allData.add(firstList);
allData.add(secondList);
Когда это доходит до внешнего интерфейса, это выглядит как на скриншоте ниже - т.е. вместо того, чтобы быть двумя объектами Array[] в одном объекте Array[], это 2 из этих объектов Resource со списком объектов Array[]. Проблема в том, что теперь я хочу перебрать этот список массивов, и я не знаю, как получить длину списка из этого объекта Resource! Я пробовал длину, размер, количество... все не определены.
Вопрос в том, как я могу заставить его хранить массив в структуре массива, чтобы я мог легко выполнять итерации? Или как получить длину от объекта Resource?
TIA (Пожалуйста, извините вопрос новичка).
Расширение одного из узлов ресурса:
2 ответа
Поведение, которое вы испытываете, так или иначе связано с тем, что в $resource
query()
где ожидаемые данные ответа являются массивом, каждый элемент данных в этом массиве преобразуется в объект ресурса, который содержит методы действий экземпляра, к которым прикреплен суффикс $
,
Как вы можете видеть в ссылке на объект ресурса выше, он выполняет shallowClearAndCopy()
копия элемента данных в массиве, которая добавляет все свойства элемента данных к самому объекту ресурса с помощью for..in
который перебирает только перечисляемые свойства. Поскольку Array.length не является перечислимым свойством, то увеличение length
Свойство в объекте Resource из массива данных элемента не происходит.
У вас есть три способа исправить эту проблему:
[ 1 ] Вы можете создать собственный метод действия, который имеет те же свойства, что и query()
метод действия, но с дополнительным определением transformResponse(). transformResponse()
Метод запускается после того, как был сделан запрос, но до разрешения любых обещаний. Он передается со строкой JSON, которую вы можете преобразовать в обычный объект json с помощью angular.fromJson(), перебрать все массивы и дополнить каждый объект элемента новым перечисляемым свойством, давайте вызовем его ._length
а затем вернуть новый десериализованный объект для получения обещаний. Таким образом, shallowClearAndCopy()
метод копирует перечисляемый _length
свойство и добавляет его к объекту ресурса.
Код выглядит примерно так:
var DataResource = $resource('data.json', null, {
'getData': {
method: 'GET',
isArray: true,
transformResponse: function(response) {
var newData = JSON.parse(response);
newData.map(function(data) {
data._length = data.length;
return data;
});
return newData;
}
}
});
DataResource.getData(function(data) {
console.log(data);
});
Вы должны заметить, что в console.log()
, это показывает, что каждый элемент объекта ресурса имеет _length
свойство, которое вы можете использовать.
[ 2 ] Другой способ заключается в использовании $http
сервис для этого конкретного случая использования, который является самым простым решением для этой проблемы, о котором я мог подумать.
$http.get('data.json').success(function(data) {
console.log(data);
});
[ 3 ] Чтобы пересмотреть структуру ваших данных ответа на что-то вроде этого:
[{
item: [1,2,3,4,5]
}, {
item: [1,2,3,4,5]
}, {
item: [1,2,3,4,5]
}, {
item: [1,2,3,4,5]
}];
Тогда вы можете просто использовать $resource
фабрика и итерации к каждому объекту элемента массива с item
ключ.
Можете ли вы обеспечить прием кода обработкой ресурса? Я предполагаю, что вы используете $resource
оказание услуг; Если вы хотите, чтобы ваши данные (например, для целей обработки), вам необходимо принять во внимание асинхронный характер ответа: доступ к ресурсам $promise
и предоставить обратный вызов для получения результатов. Код, вероятно, будет выглядеть так:
myResouce.$promise.then(function(result) {
$scope.data = result;
console.log('length = ' + $scope.data.length);
}
Если вам на самом деле не нужны ваши данные, $resource
немедленно возвращает пустой объект, который будет позже заполнен содержимым ответа. Вы могли бы просто сделать вар $scope.data = $resource(...);
и использовать этот объект данных в вашей программе просмотра. Представление может начинаться пустым, но затем обновляться всякий раз, когда данные фактически передаются $scope.data
от $resource
ответ.