Одномерный массив строк анализируется на 2d ресурсом angular

Следующий ответ JSON с сервера

[
    "hello",
    "world"
]

анализируется в 2d-массив этой службой ngResource

myService.factory('Name', function($resource){
    return $resource(site_url+'api/accounts/:accountId/names/', {}, {
        list: {method:'GET', params:{}, isArray:true}
    });
});

называется так

$scope.names = Name.list({accountId:$scope.account.id}, function(e){
    console.log(e);
});

трассировки на

[{"0":"h","1":"e","2":"l","3":"l","4":"o"},{"0":"w","1":"o","2":"r","3":"l","4":"d"}]

Любые подсказки?

Ответ 1

TL;DR; ngResource ожидает в вашем ответе объект или массив объектов.


Когда isArray установлен в true в списке действий, модуль ngResource выполняет итерацию по каждому элементу, полученному в ответе, и создает новый экземпляр ресурса. Для этого Angular выполняет глубокую копию между полученным элементом и классом Resource, который дает нам объект со специальными методами ($save, $delete и т.д.)

Проверьте источник здесь.

Внутри Angular используется angular.copy для выполнения глубокой копии, и эта функция работает только с objects и массивы, когда мы передаем строку, она будет относиться к ней как к объекту.

Строки в JS могут вести себя как массивы, обеспечивая последовательный доступ к каждому символу. angular.copy будет выдавать следующую команду при передаче строки

angular.copy('hi',{})   => {0:'h', 1:'i'}

Каждый символ становится значением в объекте, а его индекс устанавливается как ключ. ngResource предоставит ресурс со свойствами 0 и 1.


Ваши варианты:

Использовать нижний уровень $http сервис

$http.get('/res').success(function(data){
  $scope.test = data;
});

Возвращает массив объектов в вашем json-ответе

[{'data': "hello"}, {'data': "world"}] 

Перехватить ответ и изменить данные

Если вы не можете изменять данные, отправляемые сервером и хотите использовать ngResource, вам нужно будет преобразовать ответ. Прочтите, как это сделать здесь

Ответ 2

Я тоже борется с этим. Вот мое решение, скорректировав службу, используя запрос

var app = angular.module('testApp', ['ngResource']);

app.factory('Name', function($resource, $sce) {
  var path = "test.json";

  return $resource(path, {}, {
    query: {
      method: 'GET',
      isArray: false
    }
  })
});

app.controller('testController', function($scope, Name) {
  $scope.result;

  $scope.getResult = function() {
    Name.query(function(data) {
      $scope.result = data;
    });
  };

  $scope.getResult();
});

HTML:

<!DOCTYPE html>
<html ng-app="testApp">

<head>

  <link href="style.css" rel="stylesheet" />
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular-resource.min.js"></script>

  <script src="script.js"></script>
</head>

<body ng-controller="testController">
  <h1>{{result.surname}}</h1>

</body>

</html>

и файл JSON:

{
    "name": "Homer",
    "surname":  "Simpson",
    "Town": "Springfield"
}

а также работает Plunker, если интересно: http://plnkr.co/edit/SwqlZyqZ4zfcpaLxaf39

Надеюсь, что это поможет кому-то...