有一个应用程序允许用户创建或加入房间。因此RoomsListController
显示会议室RoomDetailsController
,其中显示特定会议室内活动的内容和控制。原因是RoomService
提供getRooms()
(异步)方法。
现在什么是Angular方法让两个控制器等待RoomService.getRooms()
返回的相同数据?
详细说明:
RoomService.getRooms()
不是一个选项RoomDetailsController
并不总是要求提供房间清单。每当通过$stateParams
提供的房间存在且处于活动状态时,它就会被简单显示。如果没有,有一些逻辑可以引导用户到另一个房间(这里需要房间列表)或者显示一条消息,说明没有房间可用,也许是时候创建房间了。getRooms()
对于服务器来说是一项繁重的操作,当客户端上的相同数据可以重复使用时,它不希望得到它两次。答案 0 :(得分:2)
在路由解析之前,您将调用异步方法:
// 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
}
这样,就控制器而言,在路由加载之前数据已经存在。
您已经触及其中一个关键问题是应用程序......也就是说,为应用程序可以使用它的方式组成的数据创建单一的事实来源。
有很多模式可以解决这个问题,但我建议您将路线解析承诺作为一个起点,并从那里开始分支。它会变得非常复杂。
答案 1 :(得分:1)
另一种方法可能是修改服务中的RoomService.getRooms()
函数,以在第一次调用函数时声明并存储本地promise,同时等待服务器的结果。如果再次调用该函数,您将立即返回相同的承诺。从服务器返回结果后,您可以解析存储的承诺并清除它,因此下次调用它时,将会发出新的请求。
当然,这里有足够的空间来定制。例如,如果您知道来自服务器的数据永远不会改变,那么您根本不需要清除承诺。每次要求房间时都要退货。
以下是一个示例实现:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, RoomService) {
$scope.name = 'World';
$scope.fetchingStatus = function() {
return RoomService.serverRequests ? 'Fetching... Server Requests: ' + RoomService.serverRequests : '';
};
$scope.getRooms = function() {
console.log('asking for rooms')
RoomService.getRooms().then(function(rooms) {
console.log('rooms returned: ', rooms);
$scope.rooms = rooms;
});
};
});
function RoomService($q, $timeout) {
this.$q = $q;
this.$timeout = $timeout;
this.getRoomsPromise = null;
this.serverRequests = 0;
}
RoomService.prototype.getRooms = function() {
if (!this.getRoomsPromise) {
this.getRoomsPromise = this.$q.defer();
this.getRoomsFromServer();
}
return this.getRoomsPromise.promise;
};
RoomService.prototype.getRoomsFromServer = function() {
var rooms = [];
for (var i = 1; i <= 10; i++) {
rooms.push({
id: i,
name: 'Room ' + i
});
}
console.log('fetching data from server...');
this.serverRequests++;
this.$timeout(function() {
this.serverRequests--;
this.getRoomsPromise.resolve(rooms);
this.getRoomsPromise = null;
console.log('got data from server...')
}.bind(this), 1500);
}
app.service('RoomService', RoomService);
&#13;
.fetching {
background-color: red;
color: white;
padding: 2px 10px;
display: inline-block;
margin-left: 50px;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js"></script>
<div ng-app="plunker" ng-controller="MainCtrl">
<p>
<button ng-click="getRooms()">Get Rooms</button>
<span class="fetching" ng-show="fetchingStatus()">{{fetchingStatus()}}</span>
</p>
<ul>
<li ng-repeat="room in rooms track by room.id">{{room.name}}</li>
</ul>
</div>
&#13;