angularfireCollection:知道数据何时完全加载

时间:2013-09-22 16:28:42

标签: angularjs firebase angularfire

我正在编写一个小型Angular Web应用程序,并且在加载数据时遇到了问题。我使用Firebase作为数据源,发现AngularFire项目听起来不错。但是,我无法控制数据的显示方式。

首先,我尝试使用常规隐式同步:

angularFire(ref, $scope, 'items');

它工作正常,当我在视图中使用模型$ items时显示所有数据。但是,当数据从Firebase数据源到达时,它的格式不会以视图支持的方式进行格式化,因此我需要在数据显示之前对数据进行一些额外的结构更改。问题是,我不知道数据何时完全加载。我尝试为$ items分配一个$ watch,但它被称为太早了。

所以,我继续前进并尝试使用angularfireCollection:

$scope.items = angularFireCollection(new Firebase(url), optionalCallbackOnInitialLoad);

文档不太清楚“optionalCallbackOnInitialLoad”的作用以及何时调用,但是尝试访问$ items集合中的第一项会抛出错误(“Uncaught TypeError:无法读取属性'0'未定义“)。

我尝试添加一个按钮,在按钮的点击处理程序中,我记录了$ items中第一项的内容,并且工作

console.log($scope.items[0]);
那是它!我的Firebase中的第一个对象显示没有任何错误...唯一的问题是我必须单击按钮才能到达那里。

那么,有没有人知道如何知道加载所有数据后然后将其分配给$ scope变量以显示在我的视图中?或者还有另一种方式吗?

我的控制器:

app.controller('MyController', ['$scope', 'angularFireCollection',
  function MyController($scope, angularFireCollection) {
    $scope.start = function()
    {
        var ref = new Firebase('https://url.firebaseio.com/days');
        console.log("start");

        console.log("before load?");

        $scope.items = angularFireCollection(ref, function()
        {
            console.log("loaded?");
            console.log($scope.items[0]); //undefined
        });  

        console.log("start() out");     
    };

    $scope.start();

    //wait for changes
    $scope.$watch('items', function() {
        console.log("items watch");
        console.log($scope.items[0]); //undefined
    });

    $scope.testData = function()
    {
         console.log($scope.items[0].properties); //not undefined
    };  
  }
]);

我的观点:

<button ng-click="testData()">Is the data loaded yet?</button>

提前致谢!

3 个答案:

答案 0 :(得分:2)

  

那么,有没有人知道我怎么知道什么时候加载了所有数据   然后将其分配给$ scope变量以显示在我的视图中?要么   还有另一种方式吗?

请记住,所有Firebase调用都是异步的。您的许多问题都在发生,因为您正在尝试访问尚不存在的元素。按钮单击为您工作的原因是因为您在成功加载后单击了按钮(并访问了元素)。

optionalCallbackOnInitialLoad的情况下,这是一个在angularFireCollection的初始加载完成后将执行的函数。顾名思义,它是可选的,这意味着如果你不想,你不必提供回调函数。

你可以使用它并指定一个在加载后执行的函数,或者你可以使用$q promises或你喜欢的其他promise库。我自己偏爱kriskowal's Q。我建议您阅读有关异步JavaScript的内容,以便更深入地了解其中的一些问题。

小心这个:

$scope.items = angularFireCollection(ref, function()
        {
            console.log("loaded?");
            console.log($scope.items[0]); //undefined
        });  

确实正确指定了回调函数,但在之后运行回调之后才会分配$scope.items。所以,它仍然不存在。

如果您只想查看加载$scope.items的时间,可以尝试这样的事情:

$scope.$watch('items', function (items) {
    console.log(items)
});

答案 1 :(得分:1)

在我的项目中,我还需要知道何时加载了数据。我使用了以下方法(隐式绑定):

$scope.auctionsDiscoveryPromise = angularFire(firebaseReference.getInstance() + "/auctionlist", $scope, 'auctionlist', []);

$scope.auctionsDiscoveryPromise.then(function() {
    console.log("AuctionsDiscoverController auctionsDiscoveryPromise resolved");
    $timeout(function() {
        $scope.$broadcast("AUCTION_INIT");
    }, 500);

}, function() {
    console.error("AuctionsDiscoverController auctionsDiscoveryPromise rejected");
});

当$ scope.auctionsDiscoveryPromise承诺得到解决后,我正在广播一个事件AUCTION_INIT,该事件正在我的指令中被监听。我使用了一个短暂的超时,以防一些服务或指令尚未初始化。

答案 2 :(得分:0)

我正在使用它,如果它可以帮助任何人:

function getAll(items) {

    var deferred = $q.defer();
    var dataRef = new Firebase(baseUrl + items);
    var returnData = angularFireCollection(dataRef, function(data){
            deferred.resolve(data.val());
    });
    return deferred.promise;

}