Ресурс Angularjs $не работает с массивом, возвращаемым из REST API

Я пытаюсь изучить angularjs и попал в блок при попытке привязки к массиву, возвращенному из Rest API. У меня есть простой лазурный api, возвращающий массив объектов человека. Сервисный URL http://testv1.cloudapp.net/test.svc/persons.

Мой код контроллера выглядит так:

angular.module("ToDoApp", ["ngResource"]);
function TodoCtrl($scope, $resource) {
$scope.svc = $resource('http://testv1.cloudapp.net/test.svc/persons', {
    callback: 'JSON_CALLBACK'
}, {
    get: {
        method: 'JSONP',
        isArray: true
    }
});
$scope.items = $scope.svc.get();
$scope.msg = "Hello World";
}

Мой html выглядит так:

<html>
<head></head>
<body>
<div ng-app="ToDoApp">
    <div ng-controller="TodoCtrl">
         <h1>{{msg}}</h1>

        <table class="table table-striped table-condensed table-hover">
            <thead>
                <th>Email</th>
                <th>First Name</th>
                <th>Last Name</th>
            </thead>
            <tbody>
                <tr ng-repeat="item in items">
                    <td>{{item.Email}}</td>
                    <td>{{item.FirstName}}</td>
                    <td>{{item.LastName}}</td>
                </tr>
            </tbody>
        </table>
    </div>
</div>
</body>
</html>

Вопрос. В таблице выше html не отображаются данные. Я могу увидеть вызов api в Firebug, а также увидеть ответ JSON от api. Что я делаю неправильно, что приводит к тому, что привязка данных к REST api не работает?

PS: JSFiddle демонстрирует эту проблему: http://jsfiddle.net/jbliss1234/FBLFK/4/

Ответ 1

Чтобы обрабатывать массивы с помощью службы $resource, она предложила использовать метод запроса. Как вы можете видеть ниже, метод запроса построен для обработки массивов.

{ 'get':    {method:'GET'},
  'save':   {method:'POST'},
  'query':  {method:'GET', isArray:true},
  'remove': {method:'DELETE'},
  'delete': {method:'DELETE'} };

Код, который вы должны использовать для возврата этого массива в область видимости,

angular.module("ToDoApp", ["ngResource"]);

function TodoCtrl($scope, $resource) {
    var svc = $resource('http://testv1.cloudapp.net/test.svc/persons');
    $scope.items = svc.query();
    $scope.msg = "Hello World";
}

Это предполагает, что ваш REST API работает и вернет массив.

Для дальнейшего чтения в docs

http://docs.angularjs.org/api/ngResource.$resource

Ответ 2

Просто хотел перекрестить мою адаптацию решения. Александр дал другой вопрос о стеке: fooobar.com/questions/90172/...:

methodName: {method:'GET', url: "/some/location/returning/array", transformResponse: function (data) {return {list: angular.fromJson(data)} }}

Итак, когда я вызываю эту функцию:

var tempData = ResourceName.methodName(function(){
  console.log(tempData.list); // list will be the array in the expected format
});

Очевидно, это немного громоздко, если вам нужно массивы GET в нескольких методах/ресурсах, но, похоже, это работает.

Ответ 3

Используйте параметр isArray, если у вас есть вложенные объекты:

angular.module('privilegeService', ['ngResource']).
factory('Privilege', function ($resource) {
    return $resource('api/users/:userId/privileges', 
                     {userId: '@id'}, 
                     {'query':  {method:'GET', isArray:false}});
});

Чем вы можете использовать обозначение container.object.property для доступа к объектам и его свойствам.

Ответ 5

Массив, возвращаемый с сервера, не является чистым массивом, но имеет некоторые дополнительные свойства. Это делает ng-repeat ничего не показывать, когда вы перебираете его с помощью in.

Вам нужен специальный итератор, чтобы перебрать массив с сервера, который будет игнорировать эти дополнительные свойства. Поэтому сначала извлеките данные массива через forEach, например:

$scope.items = []
var response = $scope.svc.get();
angular.forEach(response, function(item) {
  $scope.items.push(item);
});

Затем вы можете сделать

<tr ng-repeat="item in items">

Ответ 6

У меня была схожая проблема, и ответы на них не сработали для меня, вот что я сделал:

    $resource("/", {}, {
       query: {
            method: 'GET',
            isArray: false,
            transformResponse: function (data, headers) {
                //if no data return so no warnings
                if (data == ''){
                    return;
                }

                return {data: $.extend({}, eval("{" + data + '}'))};
            }
        }
   });

Использует jquery. В основном конвертируйте массив в объект так, чтобы ресурс angularjs не урезал штаны.