如何返回在角度函数中异步运行的代码的结果

时间:2015-11-13 00:19:36

标签: angularjs

我有一个功能,如果它同步运行将没有问题。但是必须加载图片,然后widthheight可用。请注意,这是从ng-style属性中的表达式调用的,该表达式尝试根据图像的纵向或横向来确定图像的css background-size属性。 但这是一个关于异步的问题;不是图像尺寸;)这是一个背景图片,而不是img标签。我动态创建Image只是为了得到尺寸。

ng-style="{'background-image': 'url(data:' + image.MimeType + ';base64,' + image.Content + ')', 'background-size': backgroundSize(image)}"
  $scope.backgroundSize = function (image) {
    var img = new Image();
    img.onload = function(){
      return img.width >= img.height ? 'cover' : 'contain';
    };
    img.src = 'data:' + image.MimeType + ';base64,' + image.Content;
  };

正如您所看到的,我正在尝试从异步代码中返回一个值,但这不起作用。执行img.onload行,然后执行img.src行,然后函数退出。我无法返回并返回数据。

我发布了最好的解决方案作为答案,但有更优雅或直接的方式吗?

1 个答案:

答案 0 :(得分:0)

Using Promises in AngularJS Views中所述,只要在模块配置中使用$parseProvider.unwrapPromises(true),就可以在从函数返回视图时自动解析promises。但是,这似乎不适用于ng-style

这个答案不是一个直接的答案,因为$scope.backgroundSize没有给调用者返回最终答案,因此据我所知,不能用作ng-style属性中的表达式。我希望得到一个更好的答案,promise将在属性中得到解决。当我尝试直接使用$scope.backgroundSize作为ng-style属性中的表达式时,它不起作用。我真的想使用$scope.backgroundSize.then()并让then()只返回我的价值!

我知道在这种情况下应用$q。它需要这样的形式:

$scope.backgroundSize = function (image) {
    var deferred = $q.defer();
    var img = new Image();
    img.onload = function() {
        deferred.resolve(img.width >= img.height ? 'cover' : 'contain');
    };
    img.src = 'data:' + image.MimeType + ';base64,' + image.Content;
    return deferred.promise;
}

这会让我接受这样的调用,这是在控制器中完成的:

$scope.backgroundSize(image).then(
  function(backgroundSize){
    image.backgroundSize = backgroundSize;
  }
);

然后我的ng-style表达式可以是:

ng-style="{'background-image': 'url(data:' + image.MimeType + ';base64,' + image.Content + ')', 'background-size': image.backgroundSize}"