2014-09-24 2 views
3

Как я могу сделать угловой код обслуживания «смотреть синхронно»?Angularjs: как я могу сделать код обслуживания «смотреть синхронно»?

Мои вопросы возникли, когда я очистил контроллер и поместил код бизнес-логики в службу. Все идет нормально. Теперь я хотел бы «подождать» в службе, пока все асинхронные вызовы не вернутся и затем. Как я могу это сделать?

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

  1. запросов некоторые данные из внутреннего интерфейса
  2. делает некоторую обработку с данными и
  3. руки данные через к области

Как что:

Dat аСопЬгоНег перед тем рефакторинга:

$scope.submitForm = function() { 

    RestBackend.query('something').then(function(data) { 

     // do some additional things ... 
     ... 

     $scope.data = data; 
    }); 
}; 

Довольно просто. Извлечь данные и заполнить область.

После рефакторинга в контроллер + службы, я закончил с:

DataController реорганизованным:

$scope.submitForm = function() { 

    DataService.getData().then(function(data) { 
     $scope.data = data; 
    }); 
}; 

DataService рефакторингу:

this.query = function() { 
    var dataDefer = $q.defer(); 

    RestBackend.query('something').then(function(data) { 

     // do some additional things ... 
     ... 

     dataDefer.resolve(data); 
    }); 
    return dataDefer.promise; 
}; 

Мне не нравится тот факт, что я также должны работать с обещанием в контроллере. Мне нравятся обещания, но я хочу сохранить агностик контроллера этой «детали реализации» службы. Это то, что я хотел бы код контроллера выглядеть следующим образом:

DataController (как это должно быть):

$scope.submitForm = function() { 

    $scope.data = DataService.getData(); 
}; 

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

  1. запроса данных (асинхронно)
  2. не возвращают, пока данные не были неправдоподобным
  3. возвращения извлеченной данные

Теперь пункт 2. не ясен для меня: как я могу «дождаться получения данных» и только потом продолжить? Цель состоит в том, что функция сервиса выглядит синхронно.

+0

Вы используете 'ngRoute' в своем проекте? – meriadec

+1

Я думаю, что у вас есть очень хорошее решение. Вам не нужно ждать, пока обещание будет разрешено, оно побеждает цель асинхронного javascript. Просто спросите себя, почему вам нужно запустить синхронизацию? Переместил мой комментарий в ответ – Tim

+0

@meriadec: да, я использую ngRoute ... но почему вы спрашиваете? – andimeier

ответ

1

Я думаю, что у вас есть очень хорошее решение. Вам не нужно ждать, пока обещание будет разрешено, оно побеждает цель асинхронного javascript. Просто спросите себя, почему вам нужно запустить синхронизацию?

Если вы полагаетесь в HTML на обещание быть решить, вы можете сделать что-то вроде этого

<div class="alert alert-warning text-center" data-ng-hide="!data.$resolved"> 
    Got data from service. 
</div> 
+0

На самом деле, я хочу подождать в коде контроллера для данных, а не в HTML-шаблоне. Во всяком случае, спасибо за типп. Кроме того, в контроллере я, конечно, хочу избегать * block * и ждать, я задавался вопросом, будет ли шаблон делать неблокирующее ожидание как-то ... – andimeier

+0

@andimeter: LOL. Non-blocking wait (a.k.a. prom: P) – gkalpak

+0

@andimeter да, к сожалению, нет ожидаемого просто обещания или метода обратного вызова. – Tim

2

Я тоже думаю, что ваше решение прекрасно.
Возвращение обещания - это не деталь реализации услуги. Он является частью API сервиса («контракт» между сервисом и потребителем услуг).

Контроллер ожидает обещание, которое разрешает данные и обрабатывает их по своему усмотрению.
Как создается это обещание, как данные извлекаются и т. Д., Это детали реализации.
Вы можете поменять место службы в любое время тем, что делает совершенно разные вещи, пока он выполняет контракт (т. Е. Возвращает обещание, которое разрешается с готовностью данных).


Тем не менее, если вы используете только данные в представлении (т.е. не непосредственно манипулировать в контроллере сразу после его неправдоподобный), который, кажется, случая, вы можете использовать ngResources подход:

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

$scope.data = DataService.getData(); 

// DataService refactored: 
this.getData = function() { 
    var data = []; 

    RestBackend.query('something').then(function(responseData) { 
     // do some additional things ... 
     ... 
     angular.forEach(responseData, function (item) { 
      data.push(item); 
     }); 
    }); 

    return data; 
}; 

Кстати, в текущем (штраф) установки, вам нужно $q.defer(). Вы можете просто использовать обещание-цепочки:

this.query = function() { 
    return RestBackend.query('something').then(function(data) { 
     // do some additional things ... 
     ... 
     return data; 
    }); 
}; 
+0

Если бы я мог принять 2 ответа, я бы тоже принял это. Я получил зеленый галочку в хронологическом первом ответе. Я хочу сказать, что здесь есть довольно полезные советы в ответе ExpertSytem. Я прибег к выходу ... – andimeier

1

Как вы используете ngRoute, я бы порекомендовал вам разрешить вам данные на вашем маршруте конфигурации, и вид будет загружен один все ваши данные будут решены ,

$routeProvider 
    .when('/your-url', { 
    templateUrl: 'path/to/your/template.html', 
    controller: 'YourCtrl', 

    // that's the point ! 
    resolve: { 
     superAwesomeData: function (DataService) { 
     return DataService.getData(); 
     } 
    } 
    }); 

Теперь superAwesomeData может быть введен в контроллере, и он будет содержит данные, решены.

angular.module('youModule') 
    .controller('YourCtrl', function (superAwesomeData) { 

    // superAwesomeData === [...]; 

    }); 
+0

Интересно. Когда-то я узнал о ngRoute. Итак, я узнал кое-что сейчас - снова;) В любом случае, AFAIU, ваше предложение отменило * экземпляр * контроллера, пока все не будет разрешено.В моем случае вместо этого у меня есть экземплярный контроллер и вы хотите приостановить поток операторов в одном методе обработчика, а не задерживать создание экземпляра контроллера. – andimeier

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