Angularjs $http 等待响应 [英] Angularjs $http wait for response

查看:27
本文介绍了Angularjs $http 等待响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 javascript/angularjs 的新手.当鼠标悬停在某些元素上时,我想显示引导弹出窗口.

I am a newbie to javascript/angularjs. I want to show a bootstrap popover when mouseover is done on some elements.

我为此创建了一个指令

(function(angular, app) {
  app.directive('popOver',["$window","$http",function($window,$http){
    return function(scope,elem,attrs){
      elem.on('mouseover',function(){
        console.log('mouseover');
        var data = scope.$apply(attrs.popOver);
        console.log('in directive again');
        console.log(data);
      });
    };
  }]);
})(angular, app);

指令的值是一个函数

<span class="asdf" pop-over="getVCard(id)">name</span>

函数 vcard(id) 在我的 angularjs 控制器中定义.它检查本地存储中是否已经存在数据,如果存在,则返回数据.否则它会执行 $http get 请求并将数据存储在 localstorage 中.

the function vcard(id) is defined in my angularjs controller. It checks if the data is already there in localstorage and if present, returns the data. otherwise it does a $http get request and stores the data in localstorage.

$scope.getVCard = function(id){

  var vcardKey = vcardKeyPrefix+id;

  var vCardFromLS = localStorageService.get(vCardKey);
  if(vCardFromLS){
    return localStorageService.get(vCardKey);
  }

  $http.get(app.common.vcardUrl(id)).
    success(function(data){
      localStorageService.set(vCardKey,data);
    }).
    error(function(error){
      F1.common.error(data,function(){});
    });

    return localStorageService.get(vCardKey);
};

由于 $http 返回 promise,我在指令中得到了 undefined 值.如何确保函数 getVCard 同步返回?

Since $http returns promise, i am getting a value of undefined in my directive. How can i make sure that the function getVCard returns synchronously?

我在谷歌搜索后阅读了一些结果.但建议的想法是使用回调.但我不确定回调将如何使这种同步.任何帮助表示赞赏.

I read a number of results after googling. But the suggested idea is to use callbacks. But i am not sure how callbacks will make this synchronous. Any help is appreciated.

UPDATE 1(回应 Foo L 的评论)我计划在多个地方使用相同的指令.vcards 和产品信息等的弹出窗口.唯一不同的是 pop-over 指令的参数.这样指令就不会只显示弹出窗口了.获取数据的位置将在传递给指令的单独函数中

UPDATE 1 (in response to Foo L's comment) i was planning to use the same directive in multiple places. popovers for vcards and product information and so on. The only thing that will differ is the argument to the pop-over directive. That way the directive will bother about just displaying the popup. Where to get the data will be in a separate function that is passed to the directive

推荐答案

你不能强制 $http.get() 进入同步.由于 $http.get() 不可避免地异步,您只能返回一个值的承诺而不是值本身.

You can't force $http.get() into synchronism. Since $http.get() is unavoidably asynchronous, you can only return a promise of a value not the value itself.

并且因为您需要在 $http.get() 调用时执行此操作,所以您还必须在其他条件下返回一个承诺 - 当 vCardFromLS 成功检索时从本地存储.这确保返回到任何 $scope.getVCard() 调用的对象都有一个 .then() 方法,即它是一个承诺,无论 $http.get() 是否被调用.

And because you need to do this when $http.get() is called, you must also return a promise under the other condition - when vCardFromLS is successfully retreived from localstorage. This ensures that the object returned to any call of $scope.getVCard() has a .then() method, ie it is a promise, regardless of whether $http.get() was called or not.

所以代码应该是这样的:

So the code should be something like this :

$scope.getVCard = function(id) {
    var vcardKey = vcardKeyPrefix + id;
    var vCardFromLS = localStorageService.get(vCardKey);
    var dfrd = $q.defer();
    if(vCardFromLS) {
        dfrd.resolve(localStorageService.get(vCardKey));
    }
    else {
        $http.get(app.common.vcardUrl(id)).success(function(data) {
            localStorageService.add(vCardKey, data);//.add() rather than .set() ?
            dfrd.resolve(data);
        }).error(function(error) {
            F1.common.error(data, function() {
                dfrd.reject('$http.get(app.common.vcardUrl(id)) failed');
            });
        });
    }
    return dfrd.promise;
};

现在您需要确保对 $scope.getVCard() 的响应得到适当处理,例如:

Now you need to ensure that the response to $scope.getVCard() is handled appropriately, eg :

$scope.getVCard(id).then(function(data) {
    //success - do whatever is required with data
}, function(reason) {
    //failure - log and/or display `reason` as an error message
})

我的......你必须在其他条件下也返回一个承诺......"是夸大其词.

My "... you must also return a promise under the other condition ..." is an overstatement.

我应该说,...你可以,让事情变得简单,在其他条件下返回一个承诺......".

I should have said, "... you can, to make things simple, return a promise under the other condition ...".

另一种可能性是根据返回的是 Promise 还是其他类型的对象/值来进行分支.然而,这很混乱,通常会导致一些代码重复.

Another possibility is to branch depending on whether a Promise or another type of object/value was returned. However, this is messy and will typically lead to some duplication of code.

这篇关于Angularjs $http 等待响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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