0

В документации на угловом ui-маршрутизаторе указано, что контроллер будет создан только после того, как все обещания будут разрешены, включая выборку данных с удаленного сервера.Ввод данных из ngResource в контроллер с разрешением ui-router

У меня есть экземпляр $ ресурса:

angular.module('app') 
    .factory('Item', item); 

item.$inject = ['$resource']; 

function item($resource) { 
    return $resource('/items/:id/', {id: '@id'}, { 
     update: {method: 'PATCH'} 
    }); 
} 

И я определяю состояние, которое принимает идентификатор из URL и извлекает данные из REST API:

 $stateProvider.state('item', { 
      url: '/item/:itemId', 
      templateUrl: '../components/item/item.html', 
      controller: 'ItemController', 
      resolve: { 
       item: function ($stateParams, Item) { 
        return Item.get({id: $stateParams.itemId}); 
       } 
      } 
     }) 

В контроллере я стараюсь используйте параметр Item, считая, что если контроллер работает, то все данные уже получены, и я могу свободно его использовать:

angular.module('app') 
    .controller('ItemController', ItemController); 

ItemController.$inject = ['$scope', 'item', 'Item']; 

function ItemController($scope, item, Item) { 

     $scope.item = item; 
     $scope.similarItems = Item.query({item_type__id: $scope.item.item_type_detail.id}); 
} 

Но браузер дает мне эту ошибку:

TypeError: Cannot read property 'id' of undefined

И указывая на точной линии, что означает, что $ scope.item.item_type_detail еще не определено, другими словами - не решена.

Но если я завершу свой второй вызов Item (в контроллере) в $ timeout, скажем, 5000 мс, он будет работать нормально, что означает, что проблема связана не с вызовом ajax или с неправильной инъекцией зависимостей, а с тем, что контроллер каким-то образом получает экземпляр перед обещанием. Как это можно объяснить и что я могу сделать, чтобы исправить это?

+0

Что означает 'Item.get ({id: ..' похоже? –

+0

@DanielB возвращает обещание, которое затем разрешает какой-либо экземпляр элемента в json-формате из REST API. –

+0

Используйте обещание '$ resource' Метод $ $ resource не возвращает завершенные данные .... он возвращает пустой объект или массив, который будет заполнен после завершения запроса. Это объясняется в документах – charlietfl

ответ

0

Возвращение обещания функции распознавателя:

$stateProvider.state('item', { 
    url: '/item/:itemId', 
    templateUrl: '../components/item/item.html', 
    controller: 'ItemController', 
    resolve: { 
     item: function ($stateParams, Item) { 
      //return Item.get({id: $stateParams.itemId}); 
      return Item.get({id: $stateParams.itemId}).$promise; 
      //return promise --------------------------^^^^^^^^^ 
     } 
    } 
}) 

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

Возвращая свойство $promise, маршрутизатор будет ожидать данные с сервера.

+0

Большое спасибо. Это фактически решило мою проблему. –

Смежные вопросы