当使用键作为 routeParam 直接链接到预期路由时,我无法将记录从 firebase 加载到我的 View 中。如下所示,在我的 routeProvider 中,我指定了稍后在 SpecController 中调用的参数。问题是,如果我直接输入 url 或单击异地链接,模型绑定(bind)都是“未定义”的,表示未加载记录。
// Snippet from RouteProvider
.when('/spec/:urlKey', {
templateUrl: 'views/spec.html',
controller: 'SpecController',
controllerAs: 'spec'
})
// Snippet from SpecController
var cKey = $routeParams.urlKey;
this.check = this.checkList.$getRecord(cKey);
经过一些研究,我似乎应该在路由提供程序中调用解析并运行第二段代码。虽然我不确定这是否是问题所在,或者它是否与 Angular 负载本身的方式和路由参数及其顺序有关。
正如旁注,当我从单独的路由/ View 加载应用程序,然后单击应用程序中的链接,然后使用 $location 设置 url 和参数时,它是完全可用的,如下所示。
// Snippet from ListController
this.viewCheck = function(check){
var ref = this.checkList.$keyAt(check);
$location.path('/spec/'+ref);
};
我指的“键”以及我正在使用和指的所有其他附加功能都可以直接在 Firebase API 指南的以下部分找到:https://www.firebase.com/docs/web/libraries/angular/guide.html#section-arrays
我真的无法在 fiddle 中重现该问题,因为它发生的唯一方法是直接将链接放在浏览器的 url 中。我制作了一个显示问题的小视频。当视频打开时,您会看到直接输入 url 的结果,然后只需单击“主页”,然后单击“返回”,它就会正确加载。 http://screencast.com/t/4OKRTVnc
最佳答案
如评论中所述,您应该使用基于 promise 的 Angular 路由解析过程。这是一个working plunkr demonstration , 但亮点是:
构建返回 Angularfire promise 的数据服务
构造和访问 Firebase 数据的方法有很多,但这里重要的是使用 Angularfire 返回的 promise 。这可以防止您为相同的数据创建重复的同步对象,并让您可以很好地使用 Angular。
testApp.factory("ChatDataService", ["$firebase",
function ($firebase) {
var rootRef = new Firebase("https://docs-examples.firebaseio.com/");
var chatDataService = {};
chatDataService.getChatRooms = function () {
if (!chatDataService.chatRoomsPromise) {
var chatRoomRef = rootRef.child("web/data/rooms");
var chatRooms = $firebase(chatRoomRef).$asArray();
chatDataService.chatRoomsPromise = chatRooms.$loaded();
}
return chatDataService.chatRoomsPromise;
};
chatDataService.getRoom = function (roomId) {
return chatDataService.getChatRooms()
.then(function (chatRooms) {
return chatRooms.$getRecord(roomId);
});
};
chatDataService.getRoomMessages = function (roomId) {
if (!chatDataService.messages || !chatDataService.messages[roomId]) {
chatDataService.messages = chatDataService.messages || {};
var roomMessagesRef = rootRef.child("web/data/messages").child(roomId);
var roomMessages = $firebase(roomMessagesRef).$asArray();
chatDataService.messages[roomId] = roomMessages.$loaded();
}
return chatDataService.messages[roomId];
};
return chatDataService;
}
]);
从解析函数返回 promise
您可以编写一个小型路由解析函数,使用您的数据服务来获取正确的数据。确保你返回一个 promise 。
when("/room/:roomId", {
controller: "RoomController",
resolve: {
room: ["$route", "ChatDataService", function ($route, chatDataService) {
var roomId = $route.current.params.roomId;
return chatDataService.getRoom(roomId);
}],
messages: ["$route", "ChatDataService", function ($route, chatDataService) {
var roomId = $route.current.params.roomId;
return chatDataService.getRoomMessages(roomId);
}]
},
templateUrl: "roomView.html"
})
让你的 Controller 保持沉默
您可以在每个 Controller 中完成所有 Firebase 查找和 promise 解析。在这种情况下,我通过让 Angular 路由等待 promise 解析来让 Controller 保持沉默。
testApp.controller("RoomController", ["$scope", "$firebase", "room", "messages",
function ($scope, $firebase, room, messages) {
$scope.room = room;
$scope.messages = messages;
}
]);
关于javascript - 解决 Firebase GetRecord 之前 View 加载不完整的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28568043/