【问题标题】:Wait for loaded data and then return in AngularFire 0.9.0等待加载的数据,然后在 AngularFire 0.9.0 中返回
【发布时间】:2014-12-26 15:02:11
【问题描述】:

我有一个表单,只有当用户提供有效的访问密钥 ($scope.access_key) 时我才希望发送该表单 - 每个密钥只能使用一次。

在我的控制器中,我有以下方法:

$scope.verifyAccess = function() {
    var ref = new Firebase(FBURL+'/keys');
    var sync = $firebase(ref);  
    $scope.keys = sync.$asArray();
    var success = false;
    $scope.keys.$loaded( function(KEYS) {
        for( var i = 0; i < KEYS.length; i++ ) {
            var e = KEYS[i];
            console.log(e.key + " " + e.used);
            if( e.key === $scope.access_key && e.used == false ) {
                e.used = true;
                $scope.keys.$save(i);
                success = true;
                break;
            }
        }
        if( success ) {
            console.log("success");
            return true;
        } else {
            console.log("failure");
            return false;
        }
    });         
}

然后我像这样使用它:

$scope.addSurvey = function() {
    if( $scope.verifyAccess() ) {
        // do something
        alert("OK");
    }
};

当我调用$scope.addSurvey() 时,我在日志中看到“成功”(并且数据库已正确修改),但alert("OK") 没有触发。

如果我不使用$loaded,方法会立即返回并且不会等待数据被加载和处理。另一方面,如果我使用$loaded,它似乎根本没有返回任何东西。

我做错了什么?

【问题讨论】:

标签: javascript angularjs firebase angularfire


【解决方案1】:

根据the documentation, $loaded() “返回一个承诺,该承诺在从 Firebase 下载初始记录后解决。”您可以使用.then 链接该承诺上的函数,或者只传递 1 个回调作为参数,就像您在上面所做的那样。但是,您是从该回调返回,而不是从 $scope.verifyAccess

您将不得不将其转换为更多异步代码。有几种方法可以做到这一点;你可以让$scope.verifyAccess 更新一些hasAccess 变量为true 然后返回一个promise。然后$scope.addSurvey 看起来像:

$scope.addSurvey = function() {
  $scope.verifyAccess()
    .then(function(){
      if( hasAccess ){
        // do something
        alert("OK");
    });
};

上述方法需要使用一个 Promise 库,该库值得学习和熟悉。或者,您可以让$scope.verifyAccess 接受一个回调,该回调在它实际验证用户是否具有访问权限时执行:

$scope.verifyAccess = function(callback) {
    var ref = new Firebase(FBURL+'/keys');
    var sync = $firebase(ref);  
    $scope.keys = sync.$asArray();
    var success = false;
    $scope.keys.$loaded( function(KEYS) {
        for( var i = 0; i < KEYS.length; i++ ) {
            var e = KEYS[i];
            console.log(e.key + " " + e.used);
            if( e.key === $scope.access_key && e.used == false ) {
                e.used = true;
                $scope.keys.$save(i);
                success = true;
                break;
            }
        }
        if( success ) {
            console.log("success");
            callback();
        } else {
            console.log("failure");
        }
    });         
}

【讨论】:

  • 非常感谢,我采用了第一种方法,效果很好。另外,我使用these examples 修改verifyAccess() 使其返回一个承诺。
  • 很好的答案基南。 @machaerus,返回承诺适用于很多用例。它允许您创建一些复杂的链,在带有resolve 的路由中使用它并执行其他惊人的异步构造。
猜你喜欢
  • 2016-12-16
  • 2021-04-27
  • 2020-06-22
  • 2019-11-13
  • 2021-11-13
  • 1970-01-01
  • 2020-03-22
  • 2019-08-01
  • 2017-02-03
相关资源
最近更新 更多