Javascript 使用factory公开一个简单的API
我正在尝试编写一个工厂,它公开一个简单的用户API。我是AngularJS的新手,对工厂和如何使用工厂有点困惑。我见过其他主题,但没有一个与我的用例很匹配 为了简单起见,我想实现的唯一功能是将所有用户放入一个数组中,然后通过注入工厂将它们传递给控制器 我将用户存储在一个json文件中(目前我只想读取该文件,而不想修改数据) users.json:Javascript 使用factory公开一个简单的API,javascript,angularjs,factory,Javascript,Angularjs,Factory,我正在尝试编写一个工厂,它公开一个简单的用户API。我是AngularJS的新手,对工厂和如何使用工厂有点困惑。我见过其他主题,但没有一个与我的用例很匹配 为了简单起见,我想实现的唯一功能是将所有用户放入一个数组中,然后通过注入工厂将它们传递给控制器 我将用户存储在一个json文件中(目前我只想读取该文件,而不想修改数据) users.json: [ { "id": 1, "name": "user1", "email": "a@b.c" }, { "id": 2
[
{
"id": 1,
"name": "user1",
"email": "a@b.c"
},
{
"id": 2,
"name": "user2",
"email": "b@b.c"
}
]
app.factory('usersFactory', ['$http', function ($http) {
return {
getAllUsers: function() {
return $http.get('users.json').then(
function(result) {
return result.data;
},
function(error) {
console.log(error);
}
);
}
};
}]);
我试图写的工厂应该是这样的:
用户工厂:
[
{
"id": 1,
"name": "user1",
"email": "a@b.c"
},
{
"id": 2,
"name": "user2",
"email": "b@b.c"
}
]
app.factory('usersFactory', ['$http', function ($http) {
return {
getAllUsers: function() {
return $http.get('users.json').then(
function(result) {
return result.data;
},
function(error) {
console.log(error);
}
);
}
};
}]);
最后,控制器调用如下所示:
.factory('usersFactory', ['$resource',
function($resource){
return $resource('http://someresource.com/users.json', {}, {
query: {
method:'GET',
isArray:true
}
})
}])
用户控制器
app.controller('UsersCtrl', ['$scope', 'usersFactory', function($scope, usersFactory){
usersFactory.getAllUsers().then(function (result) {
$scope.users = result;
});
}]);
我在网上搜索过,用这种方式使用工厂似乎不是一个好的做法,如果我想实现更多的功能,比如在数据源中添加/删除新用户,或者以某种方式将数组存储在工厂中,那就不是这样做的方法。我见过一些地方,工厂的使用类似于newusersfactory()
在尝试使用API时,使用工厂的正确方法是什么
是否可以使用包含$http.get()
结果的对象初始化工厂,然后从控制器以这种方式使用它
var usersFactory = new UsersFactory(); // at this point the factory should already contain the data consumed by the API
usersFactory.someMoreFunctionality();
我通常使用这样的工厂:
.factory('usersFactory', ['$resource',
function($resource){
return $resource('http://someresource.com/users.json', {}, {
query: {
method:'GET',
isArray:true
}
})
}])
您可以通过以下方式拨打:
usersFactory.query();
由于这是一个承诺,因此您也可以使用.then方法$http是一个承诺,这意味着您必须检查您的get调用是否工作 因此,请尝试在控制器中实现这种类型的体系结构
$http.get('users.json')
.success(function(response) {
// if the call succeed
$scope.users = result;
})
.error(function(){console.log("error");})
.then(function(){
//anything you want to do after the call
});
我看你们工厂没有什么问题。如果我理解正确,您希望添加功能。一些小的改变将使这成为可能。下面是我要做的(注意调用
getAllUsers
会消除任何更改):
app.factory('usersFactory',['$http',function($http){
var用户=[];
返回{
getAllUsers:function(){
返回$http.get('users.json')。然后(
功能(结果){
用户=结果数据;
返回用户;
},
函数(错误){
用户=[];
console.log(错误);
}
);
},
添加:功能(用户){
push(用户);
},
删除:功能(用户){
对于(var i=0;i
通常,
add
和remove
调用是http
请求(但这不是问题中的要求)。如果请求成功,您知道您的UI可以在视图中添加/删除用户。我希望API工厂返回对象,而不是只返回一个端点:
app.factory('usersFactory', ['$http', function ($http) {
return {
getAllUsers: getAllUsers,
getUser: getUser,
updateUser: updateUser
};
function getAllUsers() {
return $http.get('users.json');
}
function getUser() {
...
}
function updateUser() {
...
}
}]);
这样,如果您有任何其他与用户相关的端点,您可以在一个工厂中使用它们。另外,我更喜欢返回$http
promise目录,然后在控制器中或在工厂注入的任何地方使用then()
。我真的很喜欢。这是约翰·帕帕的例子。之后我将解释如何将此应用于您正在做的事情:
// route-config.js
angular
.module('app')
.config(config);
function config($routeProvider) {
$routeProvider
.when('/avengers', {
templateUrl: 'avengers.html',
controller: 'Avengers',
controllerAs: 'vm',
resolve: {
moviesPrepService: moviesPrepService
}
});
}
function moviesPrepService(movieService) {
return movieService.getMovies();
}
// avengers.js
angular
.module('app')
.controller('Avengers', Avengers);
Avengers.$inject = ['moviesPrepService'];
function Avengers(moviesPrepService) {
var vm = this;
vm.movies = moviesPrepService.movies;
}
基本上,在加载路由之前,您将获得所需的请求数据(在您的示例中,是您的“用户”JSON)。。。您可以将所有数据存储在
Users
工厂中(顺便说一句,您的工厂看起来不错),然后在控制器中,只需调用Users.getAll
,即可返回用户数组或,您只需从route resolve promise传递用户
,就像John Papa在其示例中所做的那样。我不能像他写的那篇文章那样公正,所以我郑重地建议你读一读。这是一种非常优雅的方法,IMHO。我一直使用$resource
使用api,这在处理restful api时为您做了很多工作。但是,在您的例子中,一个简单的http应该很好,因为您只是在处理一个简单的json文件。您没有使用api。您是要进行多个getAllUsers()
调用,还是在应用程序的生命周期内只进行一次调用?@KevinB我使用纯json只是为了简单起见,此应用程序的真正用途是使用RESTful api,但从客户的角度来看,这并不重要。@allienx我可能希望由不同的控制器使用它,它实际上不是一个特定的用例。我试图了解使用AngularJS工厂使用API的正确方式是什么。“我在网上搜索过,似乎以这种方式使用工厂并不是一个好的实践”参考?为什么这不是一个好的做法?以这种方式使用工厂会导致什么问题,与其他方法相比?我担心的是,您正在阅读大量的意见并将其作为事实。我真的建议您也阅读本教程:感谢您的回答,是否有一种方法可以使用$http.get()
,以及仅使用add()
和remove()消耗的数据初始化返回的对象
functions?现在您进入了resolve
。您使用的是ngRoute还是AngularUI路由器?我使用的是AngularUI路由器。在用户更改状态(通过单击链接或触发状态更改的按钮)和实际被发送到新状态之间,您可以获得一些不好的等待时间。在我看来,更好的用户体验是立即将它们转换到新状态,并让控制器获取数据,然后在数据准备就绪时进行渲染。