火力地堡,AngularJS和GeoFire - 等待工厂响应 [英] Firebase, AngularJS and GeoFire - wait for response from factory

查看:144
本文介绍了火力地堡,AngularJS和GeoFire - 等待工厂响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始学习了很多相关的混合应用程序编码的东西。我决定去并使用离子型框架,基于AngularJS(这给了我这个机会学习它),然后使用火力地堡作为我的后端解决方案。

I'm starting to learn a lot of things related to the hybrid apps coding. I decided to go on and use Ionic framework, based on AngularJS (this gives me the occasion to learn it), and use Firebase as my backend solution.

我想设置我的应用程序映射,所以我会定位用户和他周围的一些利益点。我发现GeoFire存在了,所以我就开始使用它。

I want to setup a map in my app, so I would locate the user and some points of interests around him. I found out GeoFire existed, so I started working with it.

我的问题:我无法在显示保存到火力地堡用户的位置。我查询它使用GeoFire,并得到响应(CONSOLE.LOG它),但它不会更新范围的变量。

My problem : I fail in displaying a user's location saved into Firebase. I query it using GeoFire, and get the response (console.log it) but it won't update the scope variable.

下面是JS code:

Here is the JS code :

myApp.factory("MyLoc", function(){
    var firebaseRef = new Firebase("https://myfirebase.firebaseio.com/geofire/");
    var geoFire = new GeoFire(firebaseRef);

    /*    geoFire.set("user_loc", [37.785326, -122.405696]).then(function() {
     console.log("Provided key has been added to GeoFire");
     }, function(error) {
     console.log("Error: " + error);
     });*/

     return geoFire.get("user_loc").then(function(location) {
        if (location === null) {
            console.log("Provided key is not in GeoFire");
            return 0;
        }
        else {
            console.log("Provided key has a location of " + location);
            return location;
        }
    }, function(error) {
        console.log("Error: " + error);
        return 0;
    });
})

myApp.controller("firstCtrl", function($scope, MyLoc) {
    $scope.data = {};

    $scope.data.myLoc = MyLoc;
});

中的HTML只是显示它:

The HTML just displays it :

{{data.myLoc}}

由于我的角度N00B,我想我失去了一些东西明显。我想我应该用一个承诺或类似的东西,只是无法弄清楚如何!有人能帮助我,好吗? :)

Since I'm an Angular N00b, I guess I'm missing something obvious. I guess I should use a promise or something similar, just can't figure out how ! Can someone help me, please ? :)

非常感谢各位兄弟!

[更新]

好了,所以,这里是回答第一个问题!

Okay so, here is the answer to the first question !

MyLoc.then(function(data){
  $scope.data.myLoc = data;

  $scope.$apply();
});

不过,我不得不使用

However I had to use

$scope.$apply();

对于HTML来显示它,显然它没有更新的时候了。你有任何想法,为什么?我的理解角度,必须通知其显示的变化,因为非常漂亮了说明:的 http://jimhoskins.com/2012/12/17/angularjs-and-apply.html

我不明白,这就是为什么它是这里的情况?为什么角不知情的变化?

What I don't understand, is why it's the case here ? Why is Angular unaware of the change ?

再次感谢!

推荐答案

你被咬伤这里的事实,火力地堡的API是异步的。

You're being bitten here by the fact that Firebase's API is asynchronous. You cannot return value from an asynchronous call in the way you're trying:

这是你的code的相关片段:

This is the pertinent fragment of your code:

myApp.factory("MyLoc", function(){
    var firebaseRef = new Firebase("https://myfirebase.firebaseio.com/geofire/");
    var geoFire = new GeoFire(firebaseRef);

     return geoFire.get("user_loc").then(function(location) {
        if (location === null) {
            console.log("Provided key is not in GeoFire");
            return 0;
        }
        else {
            console.log("Provided key has a location of " + location);
            return location;
        }
    }, function(error) {
        console.log("Error: " + error);
        return 0;
    });
})

注意那些你传递到然后的功能呢?这些被称为回调函数,并(在一般和现代网络的)异步操作的关键火力地堡的。它很容易明白为什么,如果你提取这些回调到正规,全局命名函数的结构将无法工作:

Notice those functions that you're passing into then? Those are called callback functions and are key to Firebase's (and the modern web's in general) asynchronous operation. It's easier to see why your construct won't work if you extract those callbacks into regular, global, named functions:

myApp.factory("MyLoc", function(){
    var firebaseRef = new Firebase("https://myfirebase.firebaseio.com/geofire/");
    var geoFire = new GeoFire(firebaseRef);

     return geoFire.get("user_loc").then(onGeoFireResult, onGeoFireError);
})

function onGeoFireResult(location) {
    if (location === null) {
        console.log("Provided key is not in GeoFire");
        return 0;
    }
    else {
        console.log("Provided key has a location of " + location);
        return location;
    }
}

function onGeoFireError(error) {
    console.log("Error: " + error);
    return 0;
}

当你调用 geoFire.get(user_loc)它执行到服务器的请求。该请求可能需要一些时间,我们不希望浏览器被阻塞。因此,而不是等待完成的要求,我们通过一个函数当服务器请求的数据来响应调用。因为事情可能出错,我们也通过一个函数被调用在出错的情况下。

When you call geoFire.get("user_loc") it performs a request to the server. That request may take some time and we don't want the browser to be blocked. So instead of waiting for the request to complete, we pass in a function to be called when the server responds with the requested data. Since things may go wrong, we also pass in a function to be called in case of an error.

因此​​,要意识到这一点是很重要的 onGeoFireResult onGeoFireError 在不同的时间,当你调用不是运行 geoFire.get(user_loc)。所以你不能从封装函数返回结果。相反,你必须处理的一个承诺的概念:一个结构,在某些时候会让你请求的数据

So it is important to realize that the onGeoFireResult and onGeoFireError run at a different time than when you call geoFire.get("user_loc"). So you cannot return their results from the encapsulating function. Instead you have to deal with the concept of a promise: a structure that at some point will have the data you requested.

如果您希望继续使用火力地堡和角度没有AngularFire,我的高度建议您遵循这个视频教程:的 https://www.youtube.com/watch?v=3YVlcFyxBr4 。上花费一个小时左右,将节省您在这里几十个问题。

If you want to continue using Firebase and Angular without AngularFire, I highly recommend that you follow this video tutorial: https://www.youtube.com/watch?v=3YVlcFyxBr4 . Spending an hour or so on that will save you dozens of question here.

另外设置两个断点:一个在 onGeoFireResult 一上线后 geoFire.get(user_loc)看看哪些断点触发第一次。

Alternatively set two breakpoints: one on onGeoFireResult and one on the line after geoFire.get("user_loc") and see which breakpoint triggers first.

这篇关于火力地堡,AngularJS和GeoFire - 等待工厂响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆