Обіцянка ресурсу AngularJS


75

У мене є простий контролер, який використовує $ ресурс:

 var Regions = $resource('mocks/regions.json');

 $scope.regions = Regions.query();

Я використовую цей контролер у директиві (у функції посилання)

var regions = scope.regions;

Але регіони невизначені. Цілком логічно, що дзвінок асинхронний.

Моє питання полягає в тому, як я можу зачекати на результат і регіони будуть масивом з усіма даними?

UPDATE : 

Тут визначення директиви

app.directive('ngMap', function() {
  return {
    restrict: 'EA',
    replace: 'true',
    scope: {

    },
    template: '<div id="map"></div>',
    controller: 'AccordMapCtrl',
    link: function(scope, element, attrs) {
      var regions = scope.regions;
      console.log(regions);

      for (var region in regions) {}
    };
  });

Показати визначення директиви, яке ви створили?
Chandermani

це зроблено, я додав директиву
Thomas Pons

У мене була та сама проблема, і я використав рішення @AndreyPushkarev всередині функції посилання. В основному вся логіка функції посилання знаходиться всередині $promise.then(function(result){...});.
Елліот Варгас

Тільки для того, щоб переконатися, що я не непорозумію - підхід до зворотного виклику до вирішення цієї проблеми технічно працює так само добре, як підхід „обіцянок”, правильно? (Я віддаю перевагу синтаксису обіцянок, але мені здається, що зворотні дзвінки технічно виконали б те саме)
rinogo

Так, ви отримуєте вибір $ обещання.тоді або простий зворотний дзвінок. Підхід $ обіцянки є більш "семантичним", я думаю
Томас Понс

Відповіді:


185

Якщо ви хочете скористатися асинхронним методом, вам потрібно використовувати функцію зворотного виклику за допомогою $ promis, ось приклад:

var Regions = $resource('mocks/regions.json');

$scope.regions = Regions.query();
$scope.regions.$promise.then(function (result) {
    $scope.regions = result;
});

32
Навіщо виконувати два проміжні завдання? Якщо, як я сподіваюся, Regionsне використовується в іншому місці, то resource('mocks/regions.json').query().$promise.then(function (result) { $scope.regions = result; });, безсумнівно, зробить цю роботу.
Roamer-1888

18
може бути корисно мати проміжні завдання при налагодженні коду
Джош Діл

1
З $ resource docs: ... виклик методу $ resource object негайно повертає порожнє посилання ... Це корисний трюк, оскільки зазвичай ресурс призначається моделі, яка потім відображається поданням. Якщо порожній об'єкт не відображається, як тільки дані надходять із сервера, об'єкт заповнюється даними, і подання автоматично рендериться, показуючи нові дані.
jarz

Добре, але чи не поводиться моя версія без проміжних призначень однаково? Ніщо не відображатиметься, поки не буде $scope.regions = resultвиконано.
Роумер-1888,

@ Roamer-1888 Я погоджуюсь з вами, що ваш код функціонально еквівалентний прийнятій відповіді в цій простій вправі. Однак я працюю над більш складною програмою, яка повертає дані до подання з декількох таблиць. Щоб зберегти чистіший код та реалізувати принцип СУХОСТІ, я абстрагувався від виклику об’єкта ресурсу $ на фабрику, що використовується багаторазово. Я передаю унікальну частину шляху як параметр від мого контролера на завод і повертаю дані моєму контролеру. Це вимагає від мене проміжних завдань, подібних до прийнятої відповіді.
steveo

36

Якщо ви хочете отримати обіцянку у виклику ресурсу, вам слід скористатися

Regions.query().$q.then(function(){ .... })

Оновлення: синтаксис обіцянки змінено в поточних версіях, які читаються

Regions.query().$promise.then(function(){ ..... })

Ті, хто проголосував проти, не знають, що це було, і хто перший додав цю обіцянку до ресурсного об'єкта. Я використав цю функцію наприкінці 2012 - так 2012.


Він доступний з 1.1.15. Ви можете розглянути можливість оновлення версії.
Mahbub

Я використовую 1.2 RC для реального додатка. І це критично важливий додаток, я просто не пробував деяких фантастичних речей, які вони нещодавно додали. Цю обіцянку щодо ресурсів було використано в нашому додатку минулого року в кутовому режимі. Ми щойно додали патч, який запропонував якийсь хлопець, і команда Angular зазначила "Good to Merge". Це не велика справа. Якщо вас це цікавить, тоді створіть спеціальну обгортку $ http і використовуйте її як дзвінки ресурсів, і ви отримуєте обіцянки.
Mahbub

Я обіцяю обіцянку щодо ресурсу в 1.0.8, просто синтаксис різний :)
Томас Понс,

я розміщу відповідь;)
Томас Понс,

20

Ви також можете зробити:

Regions.query({}, function(response) {
    $scope.regions = response;
    // Do stuff that depends on $scope.regions here
});

9
Однак це правильний синтаксис зворотного виклику, а не обіцянки?
ericso

0
/*link*/
$q.when(scope.regions).then(function(result) {
    console.log(result);
});
var Regions = $resource('mocks/regions.json');
$scope.regions = Regions.query().$promise.then(function(response) {
    return response;
});
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.