Angularjs 依赖于异步返回的相同数据的两个控制器

Angularjs 依赖于异步返回的相同数据的两个控制器,angularjs,angularjs-service,Angularjs,Angularjs Service,有一个允许用户创建或加入房间的应用程序。因此,有一个显示房间的RoomsListController,RoomDetailsController显示特定房间内活动的内容和控件。当然,提供getRooms()(异步)方法的RoomService 现在,让两个控制器等待由RoomService.getRooms()返回的相同数据的方法是什么 详情: 应用程序中有身份验证,房间列表取决于用户ID。因此,在应用程序启动时调用RoomService.getRooms()不是一个选项 RoomDetail

有一个允许用户创建或加入房间的应用程序。因此,有一个显示房间的
RoomsListController
RoomDetailsController
显示特定房间内活动的内容和控件。当然,提供
getRooms()
(异步)方法的
RoomService

现在,让两个控制器等待由
RoomService.getRooms()
返回的相同数据的方法是什么

详情:

  • 应用程序中有身份验证,房间列表取决于用户ID。因此,在应用程序启动时调用
    RoomService.getRooms()
    不是一个选项
  • RoomDetailsController
    并不总是请求房间列表。只要通过
    $stateParams
    提供的文件室存在并处于活动状态,它就会简单地显示出来。如果没有,则会有一些逻辑将用户引导到另一个房间(此处需要房间列表),或者显示一条消息,说明没有可用的房间,也许是时候创建一个房间了
  • 让我们假设
    getRooms()
    对于服务器来说是一项繁重的操作,当客户端上的相同数据可以重用时,不需要再获取两次
  • 我们希望逻辑不依赖于首先执行哪个控制器功能,因为这可能会受到模板中布局更新的影响
看一看

您将在路由解析之前调用async方法:

// in your config
$routeProvider.when('/your-route', {
  resolve: {
    roomData: function(RoomService) {
      return RoomService.getRooms();
    }
  }
}

// RoomsListController
function(roomData) {
  // do something with roomData
}

// RoomDetailsController
function(roomData) {
  // do something with roomData
}
这样,就控制器而言,数据在路由加载之前就已经存在了

您已经谈到了一个关键问题,即应用程序。。。也就是说,为以应用程序可以使用的方式组合的数据创建一个真实来源


有许多模式可以解决这个问题,但我建议从路由解析承诺入手,并从中进行扩展。它可能变得非常复杂。

另一种方法可能是修改服务中的
RoomService.getRooms()
函数,以便在您等待服务器结果时,在第一次调用该函数时声明并存储本地承诺。如果函数再次被调用,您将立即返回相同的承诺。一旦结果从服务器返回,您就可以解析存储的承诺并清除它,因此下次调用它时,将发出新的请求

当然,这里有很大的定制空间。例如,如果您知道来自服务器的数据永远不会更改,则根本不需要清除承诺。每次有人要房间就把它还给我

下面是一个示例实现:

var-app=angular.module('plunker',[]);
应用控制器('MainCtrl',函数($scope,RoomService){
$scope.name='World';
$scope.fetchingStatus=函数(){
return RoomService.serverRequests?'正在获取…服务器请求:'+RoomService.serverRequests:'';
};
$scope.getRooms=function(){
console.log('请求房间')
RoomService.getRooms().then(函数(房间){
console.log('返回的房间:',房间);
$scope.rooms=房间;
});
};
});
功能室服务($q,$timeout){
这.$q=$q;
这个。$timeout=$timeout;
this.getRoomsPromise=null;
this.serverRequests=0;
}
RoomService.prototype.getRooms=函数(){
如果(!this.getRoomsPromise){
this.getRoomsPromise=this.$q.defer();
这是.getRoomsFromServer();
}
返回此.getRoomsPromise.promise;
};
RoomService.prototype.getRoomsFromServer=函数(){
var房间=[];

对于(var i=1;我可以在路由的父状态下使用解析来发出请求并在服务中存储结果。只有解析了详细的代码片段后,控制器才会启动!太好了,这正是我遗漏的地方!非常感谢!