6

私は小さな Angular Web アプリケーションを作成していますが、データのロードに関して問題が発生しました。私は Firebase をデータソースとして使用しており、良いサウンドの AngularFire プロジェクトを見つけました。ただし、データの表示方法を制御するのに問題があります。

最初に、次のようにして、通常の暗黙的な同期を使用してみました。

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

ビューでモデル $items を使用すると、正常に機能し、すべてのデータが表示されました。ただし、データが Firebase データ ソースから到着するときは、ビューがサポートする形式でフォーマットされていないため、データを表示する前に、データに追加の構造変更を加える必要があります。問題は、データがいつ完全に読み込まれたか分からないことです。$watch を $items に割り当てようとしましたが、呼び出されるのが早すぎました。

そこで、次に進み、代わりに 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>

前もって感謝します!

4

3 に答える 3

2

それで、すべてのデータがいつロードされたかを知り、それを $scope 変数に割り当ててビューに表示する方法を知っている人はいますか? それとも別の方法がありますか?

すべての Firebase 呼び出しは非同期であることに注意してください。まだ存在しない要素にアクセスしようとしているために、多くの問題が発生しています。ボタンのクリックが機能した理由は、ボタンが正常に読み込まれた後にボタンをクリックした (そして要素にアクセスした) ためです。

の場合optionalCallbackOnInitialLoad、これは の初期ロードが終了した時点で実行される関数ですangularFireCollection。名前が示すように、これはオプションです。つまり、必要がなければコールバック関数を提供する必要はありません。

$qこれを使用して、ロード後に実行される関数を指定するか、promise または好みの別の promise ライブラリを使用できます。私自身、 kriskowal の 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)
});
于 2013-09-22T16:47:14.850 に答える