AngularJS ng-src异步函数

时间:2014-12-01 17:16:19

标签: javascript angularjs

我正在创建一个简单的Web应用程序来显示Formula 1驱动程序。通过公共API检索驱动程序列表。我有他们的维基百科页面的链接,所以我试图获取主图像用作个人资料图片。

我从网址中提取维基百科页面标题,然后对维基百科进行进一步的JSON调用以获取图像的网址。

获取驱动程序列表并绑定到页面工作正常,但我的函数调用似乎永远不会填充ng-src属性,即使触发了JSON调用。控制台日志记录显示返回了img url,但它从不填充img。

以下是我的controller.js

angular.module('formulaOneApp.controllers', []).controller('DriverViewController', function($scope, $stateParams, Driver) {
  $scope.data = Driver.driver.get({ id: $stateParams.id }, function(){
    $scope.driver = $scope.data.Drivers[0];
  });

  $scope.getProfilePic = function(driverName) {
    if (driverName == undefined) return;
    console.log(driverName)

    $.getJSON("http://en.wikipedia.org/w/api.php?callback=?",
    {
        action: "query",
        titles: driverName,
        prop: "pageimages",
        format: "json",
        pithumbsize: "200"
    }, function(data) {
        $.each(data.query.pages, function(i,item){
            console.log(item.thumbnail.source)
            return item.thumbnail.source;
        });
    });
  }
});

这是我的HTML: -

<h3>Details for {{driver.givenName}} {{driver.familyName}}</h3>
<img ng-src="{{ getProfilePic(driver.wikiName) }}" />

我怀疑这可能不是正确的方法,所以有人能指出我正确的方向吗?

1 个答案:

答案 0 :(得分:1)

getProfilePic(...)的实施会检索数据,但您实际上并未将源路径保存在任何位置。要正确处理此问题,您不会将数据检索调用放入ng-src属性(因为它将在每个$digest上重复执行)。相反,您可以直接从控制器进行检索调用

$scope.data = Driver.driver.get({ id: $stateParams.id }, function(){
    $scope.driver = $scope.data.Drivers[0];
    $scope.getProfilePic($scope.driver.wikiName).then(function (url) {
        $scope.driver.imageUrl = url;
    });
});

$scope.getProfilePic = function(driverName) {
    return $http.get("http://en.wikipedia.org/w/api.php?callback=?", { ... }, function (data) {
        // ... get the image URL from the data and return it
    });
});

并将您获得的URL保存到范围变量中。然后只需从模板链接到该变量:

<img ng-src="{{driver.imageUrl}}">

(我之前只使用$http.get代替$.getJSON,因为我不使用jQuery。请随意调整该位,但请记住jQuery AJAX方法不要退回AngularJS的承诺。)


免费奖金提示:无论是使用jQuery promises还是AngularJS promises,都要了解它们是如何被链接的。在AngularJS中,控制器代码的干净版本如下所示:

getDriver($stateParams.id)
    .then(function (driver) {
        $scope.driver = driver;
    })
    .then(function () {
        return getDriverImageUrl($scope.driver.wikiName);
    })
    .then(function (url) {
        $scope.data.imageUrl = url;
    });

function getDriver (id) {
    return $http({
        // ...
    });
}
function getDriverImageUrl (driverName) {
    return $http({
        // ...
    });
}