Ani*_*n J 4 javascript asynchronous promise angularjs angularjs-directive
我是javascript/angularjs的新手.我想在一些元素上完成鼠标悬停时显示一个引导弹出窗口.
我为此创建了一个指令
(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);
Run Code Online (Sandbox Code Playgroud)
指令的值是一个函数
<span class="asdf" pop-over="getVCard(id)">name</span>
函数vcard(id)在我的angularjs控制器中定义.它检查数据是否已存在于localstorage中,如果存在,则返回数据.否则它会执行$ http get请求并将数据存储在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);
};
Run Code Online (Sandbox Code Playgroud)
由于$ http返回promise,我在我的指令中获得了undefined值.如何确保函数getVCard同步返回?
我在google搜索后阅读了一些结果.但建议的想法是使用回调.但我不确定回调将如何使这种同步.任何帮助表示赞赏.
更新1(响应Foo L'的评论)我计划在多个地方使用相同的指令.弹出用于vcards和产品信息等.唯一不同的是pop-over指令的参数.这样,该指令将只是显示弹出窗口.获取数据的位置将在传递给指令的单独函数中
Bee*_*oot 10
你不能强迫$http.get()同步.由于$http.get()不可避免地是异步的,因此您只能返回值的承诺而不是值本身.
并且因为在$http.get()调用时需要执行此操作,所以还必须在其他条件下返回promise - vCardFromLS从localstorage成功返回的时间.这确保返回到任何调用的对象$scope.getVCard()都有一个.then()方法,即它是一个promise,无论是否$http.get()被调用.
所以代码应该是这样的:
$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;
};
Run Code Online (Sandbox Code Playgroud)
现在您需要确保$scope.getVCard()正确处理响应,例如:
$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
})
Run Code Online (Sandbox Code Playgroud)
编辑:
我的"......你必须在另一个条件下回复承诺......"是夸大其词.
我应该说,"......你可以,为了简单起见,在另一个条件下回复承诺......".
另一种可能性是根据是否返回Promise或其他类型的对象/值进行分支.但是,这很麻烦,通常会导致一些代码重复.
| 归档时间: |
|
| 查看次数: |
19202 次 |
| 最近记录: |