【问题标题】:In AngularJS, how do I automatically update a value fetched via ajax?在 AngularJS 中,如何自动更新通过 ajax 获取的值?
【发布时间】:2013-08-16 15:16:58
【问题描述】:

我想做一个从 ajax URL 获取一些信息的函数。例如,在我的服务中,我会有以下方法:

this.getFavColor = function(id)
{
    return $http.get('/colors/get/' + id);
}

在我的控制器中,我会执行以下操作:

$scope.favColor = UserService.getFavColor( id );

但问题是,$scope.favColor 在这种情况下将被分配一个承诺,而将其实际更改为 ajax 返回的值的唯一方法是在承诺上设置一个.success() 回调并将其用于更新值。

但是,如果我有很多必须通过 ajax 获取的东西,这很快就会变得很麻烦。有没有捷径,比如可以这样做?

this.getFavColor = function(id, variableToChange)
{
    return $http.get('/colors/get/' + id).success(function(jsonResult)
       {
         variableToChange = jsonResult.favColor;
       });
}

然后在控制器中执行以下操作:

UserService.getFavColor( id, $scope.favColor );

这种方法真的有效吗?

注意:我已经考虑过$resource,但我无法为我的 ajax 设置 REST api,所以请不要建议。

【问题讨论】:

  • 这应该可以。你试过了吗?我唯一的疑问是,因为 return 语句不是直接返回承诺,而是调用成功方法。如果成功也返回承诺,那很好。否则你不需要返回任何东西或先将promise放入一个变量中,然后对其调用success,然后返回promise。
  • @Chandermani 我没有尝试过,但我更喜欢使用$resource 使用的任何方法来执行此操作。你看过angular.resource.js的代码,你能弄清楚它是怎么做到的吗?
  • 您不需要 REST API 即可使用 $resource 获取数据。只要数据是 json GET 就可以正常工作。它只需要一个 url 来获取数据。
  • 看看http://stackoverflow.com/questions/11966252/how-does-the-resource-get-function-work-synchronously-in-angularjs,我正在使用此处描述的方法来执行此操作。一旦它工作,我会发布一个答案
  • 是否值得将您的 favColor 移动到服务而不是控制器中?我知道这不是你要问的,但它避免了这个问题。否则你的控制器真的需要知道它是异步的并自己处理承诺

标签: javascript angularjs


【解决方案1】:

$resource 这样做的方式是立即返回一个空对象,然后在响应从服务器到达时将数据添加到该对象。这就是为什么 $resource 只能返回对象或数组,而不能返回原语的原因。

ng-bind(和简写 {{ }})实际上解决了 Promise,所以这可能是一个更好的解决方案。我用三个不同的例子创建了一个 plnkr:http://plnkr.co/edit/WOrU5eMOmsgK4wuiSCHu?p=preview

// data.json: {"color":"Blue"}

app.service('UserService',function($http, $q){
  return {

    // return value can be accessed by {{value.data.color}}
    getFavColor: function(id){
      return $http.get('data.json');
    },

    // return value can be accessed by {{value}}
    getFavColorWithQ: function(id){
      var def = $q.defer();
      $http.get('data.json').success(function(data){
        def.resolve(data.color);
      });
      return def.promise;
    }

    // return value can be accessed by {{value.color}}
    ,resourceExample: function(id){
      var response = {};
      $http.get('data.json').success(function(data){
        response.color = data.color;
      });
      return response;
    }
  }
});

【讨论】:

  • 对我来说,第三个选项似乎没有更新视图,似乎它不会触发 angularjs 的手表。可能需要$scope.$apply,但对我来说,我收到了digest already in progress 消息。然而,第二种方法效果很好。
  • 第一种方法只会返回承诺,你必须使用success回调,对吧?
  • 你看到我的 plnkr 例子了吗?它显示了所有方法的工作原理,您不必在其中任何一个中使用回调方法。但是第一个和第二个例子都返回了 Promise,只是第一个例子返回了一个 Promise 给一个响应对象,而第二个例子返回了一个 Promise 给一个值
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-07
  • 1970-01-01
  • 1970-01-01
  • 2015-12-29
相关资源
最近更新 更多