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

iaf*_*wik 5 angularjs firebase angularfire

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

起初我尝试使用常规隐式同步:

angularFire(ref, $scope, 'items');
Run Code Online (Sandbox Code Playgroud)

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

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

$scope.items = angularFireCollection(new Firebase(url), optionalCallbackOnInitialLoad);
Run Code Online (Sandbox Code Playgroud)

文档不是很清楚"optionalCallbackOnInitialLoad"的作用以及何时调用它,但是尝试访问$ items集合中的第一项将引发错误("Uncaught TypeError:无法读取未定义的属性'0'") .

我尝试添加一个按钮,在按钮的单击处理程序中,我记录了$ items中第一项的内容,并且它有效:

console.log($scope.items[0]);
Run Code Online (Sandbox Code Playgroud)

那是它!我的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
    };  
  }
]);
Run Code Online (Sandbox Code Playgroud)

我的看法:

<button ng-click="testData()">Is the data loaded yet?</button>
Run Code Online (Sandbox Code Playgroud)

提前致谢!

Eri*_*ger 2

那么,有谁知道我如何知道所有数据何时已加载,然后将其分配给 $scope 变量以显示在我的视图中?或者还有别的办法吗?

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

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

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

请注意:

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

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

如果您只想查看何时$scope.items加载,您可以尝试这样的操作:

$scope.$watch('items', function (items) {
    console.log(items)
});
Run Code Online (Sandbox Code Playgroud)