Angularfire child_added

时间:2014-04-09 11:08:53

标签: javascript angularjs asynchronous firebase

所以我最近开始使用AngularFire,因为它使得后端的使用完全没用。

我试图在注册表中看到电子邮件是否已存在。目前在firebase中有一个emailaddress'xxx',但是由于我一直得到一个未定义的函数,我无法添加第二个条目。为了澄清,这是我的控制器中的代码:

 $scope.submitForm = function (isValid) {
        if (isValid) {
            var resolved = checkEmail($scope.add.email);
            console.log('resolved = ' + resolved);
            if (resolved) {
                console.log('I should be here');
                $scope.addEntry();
            } else if (!resolved) {
                console.log('Am I seriously getting in here ???');
            }
        } else {
            alert('failed!')
        }
    };

var db = new Firebase("https://radiant-fire-1289.firebaseio.com/");

function checkEmail(inputEmail) {
    db.on('child_added', function (snapshot) {
        var data = snapshot.val();
        if (data.email.toUpperCase() === inputEmail.toUpperCase()) {
            return false;
        } else {
            console.log('I am in checkEmail');
            return true;
        }
    })
}

inputEmail显然是我在html表单中输入的电子邮件。提交电子邮件地址'bbb'时,该函数正确返回true,它不等于'xxx'。按下提交按钮时,从表单调用submitForm函数。 isValid只是对表单的一些验证,这是正常的。但是,布尔“已解决”始终未定义。我觉得这与异步函数有关,但是因为我是javascript的新手(尤其是firebase),我很难理解我做错了什么。

在记录'resolved ='+已解决之前,控制台会记录'我在checkEmail',但是已解决将打印保持为undefined而不是true。然后控制台打印出“我是否真的到了这里?”这导致没有添加任何条目。 (我猜undefined与编译器的假值相同?)

1 个答案:

答案 0 :(得分:0)

on函数是异步的。这意味着直到远程调用Firebase完成后才会执行回调。 checkEmail函数在获取结果之前已经运行,因此没有返回值。你可以通过在checkEmail结束之前添加一个console.log来测试这个,你会注意到它在“我在checkEmail”日志之前运行。

此外,这里存在对范围的误解。在db.on回调中返回false / true不会以某种方式传播到checkEmail,因此checkEmail的结果将始终未定义,即使这是同步调用。

要正确执行此操作,您需要在获取结果时调用另一个回调:

$scope.submitForm = function (isValid) {
        if (isValid) {
            var resolved = checkEmail($scope.add.email, function(resolved) {
               console.log('resolved = ' + resolved);
               if (resolved) {
                 console.log('I should be here');
                 $scope.addEntry();
               } else if (!resolved) {
                 console.log('Am I seriously getting in here ???');
               }
            });
        } else {
            alert('failed!')
        }
    };

var db = new Firebase(URL);

function checkEmail(inputEmail, callback) {
    db.on('child_added', function (snapshot) {
        var data = snapshot.val();
        if (data.email.toUpperCase() === inputEmail.toUpperCase()) {
            callback(false);
        } else {
            console.log('I am in checkEmail');
            callback(true);
        }
    })
}

最后但同样重要的是,您需要了解Angular's HTML compiler$qchild_added事件不会在Angular的编译范围内被触发(因为它是异步的),因此如果对$ scope进行任何更改,则需要使用$timeout手动触发编译。

参见Firebase + Angular Getting Started Guide,它将向您介绍正确的集成方法,并提供一个名为angularFire的lib,代表您处理所有这些复杂问题。