javascript - 解决 Firebase GetRecord 之前 View 加载不完整的问题

标签 javascript angularjs firebase route-provider

当使用键作为 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/

相关文章:

javascript - Backbone.js 分组集合

javascript - JQuery 添加(数学)输入值

javascript - 提交前更改 ng-model

java - 谷歌使用 Firebase 登录时的唯一 ID

ios - 或者在 whereField 中从 Firestore 中获取文档

javascript - Express.js 路由器中的正则表达式

javascript - 如何通过命令行在 Windows 上卸载 node-gyp

javascript - AngularJs Controller 获取请求未命中 Spring MVC Rest 服务

javascript - 使用 ng-repeat 在列表上分页

ios - 如何设置关联域/通用链接