将 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.js
、controllers.js
、services.js
、filters.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
被传递给控制器函数,并由注入 main 应用程序模块中的服务模块提供。
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 httpClient 将响应映射到具有行为的实体