【问题标题】:What is the best practice for making an AJAX call in Angular.js?在 Angular.js 中进行 AJAX 调用的最佳实践是什么?
【发布时间】:2013-07-12 19:59:41
【问题描述】:

我正在阅读这篇文章:http://eviltrout.com/2013/06/15/ember-vs-angular.html

它说,

由于它缺乏约定,我想知道有多少 Angular 项目 依赖不好的做法,例如直接在控制器中调用 AJAX? 由于依赖注入,开发人员是否在注入路由器 参数转换成指令? AngularJS 开发新手会去吗 以经验丰富的 AngularJS 开发人员的方式构建他们的代码 相信是惯用的?

我实际上是从我的 Angular.js 控制器进行$http 调用。为什么这是一个不好的做法?那么,拨打$http 电话的最佳做法是什么?为什么?

【问题讨论】:

标签: angularjs


【解决方案1】:

我为想要在 Angular 中提供完全通用的 Web 服务的人提供了一个答案。我建议只插入它,它会处理您所有的 Web 服务调用,而无需自己编写所有代码。答案就在这里:

https://stackoverflow.com/a/38958644/5349719

【讨论】:

    【解决方案2】:

    接受的答案是给我$http is not defined 错误,所以我必须这样做:

    var policyService = angular.module("PolicyService", []);
    policyService.service('PolicyService', ['$http', function ($http) {
        return {
            foo: "bar",
            bar: function (params) {
                return $http.get('../Home/Policy_Read', {
                    params: params
                });
            }
        };
    }]);
    

    主要区别在于这一行:

    policyService.service('PolicyService', ['$http', function ($http) {
    

    【讨论】:

      【解决方案3】:

      编辑:这个答案主要关注版本 1.0.X。为防止混淆,它已被更改以反映截至今天 2013 年 12 月 5 日所有当前版本的 Angular 的最佳答案。

      这个想法是创建一个服务,该服务向返回的数据返回一个承诺,然后在您的控制器中调用它并在那里处理承诺以填充您的 $scope 属性。

      服务

      module.factory('myService', function($http) {
         return {
              getFoos: function() {
                   //return the promise directly.
                   return $http.get('/foos')
                             .then(function(result) {
                                  //resolve the promise as the data
                                  return result.data;
                              });
              }
         }
      });
      

      控制器:

      处理 promise 的 then() 方法并从中获取数据。设置 $scope 属性,然后做您可能需要做的任何其他事情。

      module.controller('MyCtrl', function($scope, myService) {
          myService.getFoos().then(function(foos) {
              $scope.foos = foos;
          });
      });
      

      In-View Promise Resolution(仅限 1.0.X):

      在 Angular 1.0.X 中,这里原始答案的目标,承诺将得到视图的特殊处理。当它们解析时,它们的解析值将绑定到视图。 这在 1.2.X 中已被弃用

      module.controller('MyCtrl', function($scope, myService) {
          // now you can just call it and stick it in a $scope property.
          // it will update the view when it resolves.
          $scope.foos = myService.getFoos();
      });
      

      【讨论】:

      • 顺便提一下,这仅在您在模板中使用 $scope.foos 属性时才有效。如果您要在模板之外(例如在另一个函数中)使用相同的属性,则存储在那里的对象仍然是一个 Promise 对象。
      • 我目前在一个新的 Angular 应用程序中使用这种模式,但是我想知道如何在一个杂乱无章的页面中访问我绑定到范围的属性,在这个例子中,如果我想采取来自 getFoos 的数据并对其进行更改。如果我尝试在更新中访问 $scope.foos,我有 promise 对象而不是数据,我可以看到如何在对象本身中获取数据,但它看起来真的很 hacky.ideas?
      • @KellyMilligan,在这个模式中,binding 知道如何处理 promise。如果您需要从其他任何地方访问该对象,您将不得不处理 promise 的 .then() 并将值放入 $scope...myService.getFoos().then(function(value) { $scope.foos = value; });
      • 只是这项技术的更新,从 1.2.0-rc.3 开始,承诺的自动解包已被弃用,因此该技术将不再有效。
      • 最近在这里得到了一些反对意见,大概是因为它不再与最新版本的 Angular 保持一致。我已经更新了答案以反映这一点。
      【解决方案4】:

      最佳做法是将$http 调用抽象为向控制器提供数据的“服务”:

      module.factory('WidgetData', function($http){
          return {
              get : function(params){
                  return $http.get('url/to/widget/data', {
                      params : params
                  });
              }
          }
      });
      
      module.controller('WidgetController', function(WidgetData){
          WidgetData.get({
              id : '0'
          }).then(function(response){
              //Do what you will with the data.
          })
      });
      

      像这样抽象$http 调用将允许您跨多个控制器重用此代码。当与此数据交互的代码变得更加复杂时,这变得很有必要,也许您希望在控制器中使用它之前处理数据,并缓存该过程的结果,这样您就不必花时间重新处理它。

      您应该将“服务”视为您的应用程序可以使用的数据的表示(或模型)。

      【讨论】:

        猜你喜欢
        • 2013-03-04
        • 2013-01-07
        • 2020-03-19
        • 2019-03-16
        • 2013-05-17
        • 1970-01-01
        • 2018-02-14
        • 2013-10-03
        • 1970-01-01
        相关资源
        最近更新 更多