将 Angular HTTP.get 函数转换为服务

Posted

技术标签:

【中文标题】将 Angular HTTP.get 函数转换为服务【英文标题】:Convert Angular HTTP.get function to a service 【发布时间】:2012-12-05 21:58:50 【问题描述】:

我正在尝试将 controllers.js 中的 Angular HTTP.get 函数转换为 services.js 中的服务。

我发现的示例都有相互冲突的服务实现方式,并且它们的名称选择令人困惑。此外,服务的实际 Angular 文档使用的语法与所有示例不同。我知道这非常简单,但请在这里帮助我。

我有app.jscontrollers.jsservices.jsfilters.js

app.js

angular.module('MyApp', []).
    config(['$routeProvider', function($routeProvider)
        
            $routeProvider.
                when('/bookslist', templateUrl: 'partials/bookslist.html', controller:             BooksListCtrl).
                otherwise(redirectTo: '/bookslist');
        
    ]);

controllers.js

function BooksListCtrl($scope,$http) 
    $http.get('books.php?action=query').success(function(data) 
        $scope.books = data;
    );

    $scope.orderProp = 'author';

【问题讨论】:

【参考方案1】:

考虑模块和依赖注入。

假设你有这三个文件

<script src="controllers.js"></script>
<script src="services.js"></script>
<script src="app.js"></script>

你需要三个模块

1。主应用模块

angular.module('MyApp', ['controllers', 'services'])
  .config(['$routeProvider', function($routeProvider)
    $routeProvider
      .when('/bookslist', 
        templateUrl: 'partials/bookslist.html', 
        controller:  "BooksListCtrl"
      )
      .otherwise(redirectTo: '/bookslist');
  ]);

请注意,其他两个模块被注入到主模块中,因此它们的组件可用于整个应用程序。

2。控制器模块

当前您的控制器是一个全局函数,您可能希望将其添加到控制器模块中

angular.module('controllers',[])
  .controller('BooksListCtrl', ['$scope', 'Books', function($scope, Books)
    Books.get(function(data)
      $scope.books = data;
    );

    $scope.orderProp = 'author';
  ]);

Books 被传递给控制器​​函数,并由注入 ma​​in 应用程序模块中的服务模块提供。

3。服务模块

这是您定义Books 服务的地方。

angular.module('services', [])
  .factory('Books', ['$http', function($http)
    return
      get: function(callback)
          $http.get('books.json').success(function(data) 
          // prepare data here
          callback(data);
        );
      
    ;
  ]);

有多种注册服务的方式。

service:传递一个构造函数(我们可以称它为类)并返回该类的一个实例。 provider:最灵活和可配置的,因为它允许您在实例化服务时访问注入器调用的函数 factory:传递给注入器在实例化服务时调用的函数。

我更喜欢使用factory 函数并让它返回一个对象。在上面的示例中,我们只返回一个带有 get 函数的对象,该函数被传递了一个成功回调。您也可以更改它以传递错误函数。


编辑 在 cmets 中回答 @yair 的请求,这是您将服务注入指令的方法。

4。指令模块

我按照惯用的模式,先添加js文件

<script src="directives.js"></script>

然后定义一个新模块并注册一些东西,在这种情况下是一个指令

angular.module('directives',[])
  .directive('dir', ['Books', function(Books)
    return
      restrict: 'E',
      template: "dir directive, service: name",
      link:function(scope, element, attrs)
        scope.name = Books.name;
      
    ;
  ]);

directive模块注入app.js中的主模块

angular.module('MyApp', ['controllers', 'services', 'directives']) 

您可能希望遵循不同的策略并将模块注入 directives 模块

请注意,内联依赖注释的语法几乎对所有内容都是相同的。该指令被注入相同的图书服务。

更新 Plunker:http://plnkr.co/edit/mveUM6YJNKIQTbIpJHco?p=preview

【讨论】:

让我首先非常感谢您提供非常详细的答案/解释。在这一行: .controller('BooksListCtrl', ['$scope', 'Books', function($scope, Books) 你能解释一下参数吗? 第一个参数是你的控制器的名字,第二个是一个数组。该数组包含一个服务列表,包括在服务模块中定义的Book 服务。数组中的最后一项是将注入这些服务的函数。这种样式称为 inline 注入,用于在代码缩小时使您的应用程序正常工作。 AngularJS 使用函数参数来推断要注入什么,第二个参数明确告诉 Angular 的注入器要注入什么。 @jm- 您能否详细说明您的答案并展示如何将服务注入directive?谢谢! @YairNevet,我刚刚添加了一个示例 很好的答案,这应该在 angularjs.org 的最佳实践部分中【参考方案2】:

这里是服务服务的实现,而不是上面提到的工厂服务。希望对您有所帮助。

app.js

angular.module('myApp', ['controllers', 'services'])
 .config(['$routeProvider', function($routeProvider)
    $routeProvider
      .when('/bookslist', 
        templateUrl: 'partials/bookslist.html', 
        controller:  "BooksListCtrl"
      )
      .otherwise(redirectTo: '/bookslist');
  ]);

service.js

angular.module('services', [])
  .service('books', ['$http', function($http)
      this.getData = function(onSuccess,onError)
          $http.get('books.json').then(
              onSuccess,onError);
        
  ]);

controller.js

angular.module('controllers',[])
    .controller('BooksListCtrl', ['$scope', 'books', function($scope, books)
       $scope.submit = function()

        $scope.books = books.getData($scope.onSuccess,$scope.onError);
       
           $scope.onSuccess = function(data)
           console.log(data);
           $scope.bookName = data.data.bookname;
           

           $scope.onError = function(error)
               console.log(error);
           
  ]);

【讨论】:

以上是关于将 Angular HTTP.get 函数转换为服务的主要内容,如果未能解决你的问题,请参考以下文章

带有 TypeScript 错误的 Angular HTTP GET http.get(...).map 不是 [null] 中的函数

angular js中 http.get方法怎么用

什么是 Angular 中的 pipe() 函数

Angular httpClient 将响应映射到具有行为的实体

Angular 5 管理带有 blob 响应和 json 错误的 http get

Angular:将字符串数组映射到http get调用中的枚举值数组