14

我仍然在围绕 Angular.JS 绞尽脑汁。

我有两个独立的 $http 调用,它们从远程 Web 服务中检索数据。我有一个动作,我想在两个服务调用都完成后触发。

  1. 第一个服务调用将填充 $scope.model
  2. 第二个服务调用,修改 $scope.model 中的数据(它添加了一些在视图中呈现的计数器属性)

另一个独特的要求是最终将在控制器外部调用第二个服务调用并使用 $scope.model 进行更新。这是一个通知消息泵。

我猜我将使用 promises $q 和可能的 $service,但我不太确定从哪里开始遵循一些最佳实践。

我知道在这里异步调用听起来不合适,因为我的示例可以通过同步进行来简化。但是,第二个服务调用是一个通知更新程序,因此它会不断地轮询到服务器(最终将使用 websocket)。

这是我将在此应用程序中看到的常见模式。

4

2 回答 2

29

你会想要使用 $q 承诺。特别是 $q.all()。所有的 $http 方法都会返回 Promise。$q.all([promise, promise, promise]).then(doSomething)将等待所有承诺解决,然后调用doSomething将一组承诺结果传递给它。

app.service('myService', ['$http', '$q', function($http, $q) {
   return {
      waitForBoth: function() { 
          return $q.all([
             $http.get('/One/Thing'),
             $http.get('/Other/Thing')
          ]);
      };
   }
}]);

然后调用它:

app.controller('MyCtrl', ['$scope', 'myService', function($scope, myService) {
   myService.waitForBoth().then(function (returnValues){
       var from1 = returnValues[0].data;
       var from2 = returnValues[1].data;
       //do something here.
   });
}]);

这是为您演示的Plunker

于 2013-02-27T16:53:55.863 回答
2

为您的第一个服务调用创建服务。皮特的回答将对此有所帮助:https ://stackoverflow.com/a/12513509/215945

在您的控制器中,在 then() 回调中,为适当的 $scope.model 属性添加一个 $watch:

app.controller('MainCtrl', function(myService, $scope) {
  myService.async().then(function(myData) {
    $scope.model = myData;
    $scope.$watch('model.???', function(newVal, oldVal) {
      if(newVal !== oldVal) {
         // do something here, now that $scope.model.??? has changed
      }
    })
  });
});
于 2013-02-27T16:50:21.017 回答