使用工厂公开一个简单的 API
Using factory to expose a simple API
我正在尝试编写一个公开简单用户的工厂 API。我是 AngularJS 的新手,我对工厂以及如何使用它们有些困惑。我看过其他主题,但 none 非常适合我的用例。
为了简单起见,我想要实现的唯一功能是将所有用户放入一个数组中,然后通过注入的工厂将它们传递给控制器。
我将用户存储在一个 json 文件中(目前我只想读取该文件,不修改数据)
users.json:
[
{
"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);
}
);
}
};
}]);
最后,控制器调用将是这样的:
用户控制器
app.controller('UsersCtrl', ['$scope', 'usersFactory', function($scope, usersFactory){
usersFactory.getAllUsers().then(function (result) {
$scope.users = result;
});
}]);
我在网上搜索了一下,似乎以这种方式使用工厂并不是一个好的做法,如果我想实现更多功能,比如 adding/removing 新用户 to/from 数据源,或者以某种方式将数组存储在工厂中,这不是实现它的方法。我看到一些地方使用工厂是像 new UsersFactory()
.
尝试使用 APIs 时使用工厂的正确方法是什么?
是否可以使用包含 $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 users = [];
return {
getAllUsers: function() {
return $http.get('users.json').then(
function(result) {
users = result.data;
return users;
},
function(error) {
users = [];
console.log(error);
}
);
},
add: function(user) {
users.push(user);
},
remove: function(user) {
for(var i = 0; i < users.length; i++) {
if(users[i].id === user.id) { // use whatever you want to determine equality
users.splice(i, 1);
return;
}
}
}
};
}]);
通常 add
和 remove
调用是 http
请求(但这不是您在问题中要求的)。如果请求成功,您知道您的 UI 可以 add/remove 视图中的用户。
我喜欢我的 API 工厂到 return 个对象而不是只有一个端点:
app.factory('usersFactory', ['$http', function ($http) {
return {
getAllUsers: getAllUsers,
getUser: getUser,
updateUser: updateUser
};
function getAllUsers() {
return $http.get('users.json');
}
function getUser() {
...
}
function updateUser() {
...
}
}]);
这样,如果您有任何其他与用户相关的端点,您可以在一个工厂中使用它们。另外,我的偏好是 return $http
promise 目录并在控制器中使用 then()
或者你注入工厂的地方。
我真的是route resolve promises的粉丝。这是约翰爸爸的例子。之后我会解释如何将其应用到您正在做的事情中:
// 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;
}
基本上,在你的路线加载之前,你会得到你需要的请求数据(在你的情况下,你的 "users" JSON。)你有几个选择......你可以存储所有Users
工厂中的数据(顺便说一句,你的工厂看起来不错),然后在你的控制器中,只需调用 Users.getAll
,它可以只是 return 用户数组。 或,你可以直接从路由 resolve promise 中传入 users
,就像 John Papa 在他的例子中所做的那样。我不能像他写的文章那样公正,所以我强烈推荐阅读它。恕我直言,这是一种非常优雅的方法。
我正在尝试编写一个公开简单用户的工厂 API。我是 AngularJS 的新手,我对工厂以及如何使用它们有些困惑。我看过其他主题,但 none 非常适合我的用例。
为了简单起见,我想要实现的唯一功能是将所有用户放入一个数组中,然后通过注入的工厂将它们传递给控制器。
我将用户存储在一个 json 文件中(目前我只想读取该文件,不修改数据)
users.json:
[
{
"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);
}
);
}
};
}]);
最后,控制器调用将是这样的:
用户控制器
app.controller('UsersCtrl', ['$scope', 'usersFactory', function($scope, usersFactory){
usersFactory.getAllUsers().then(function (result) {
$scope.users = result;
});
}]);
我在网上搜索了一下,似乎以这种方式使用工厂并不是一个好的做法,如果我想实现更多功能,比如 adding/removing 新用户 to/from 数据源,或者以某种方式将数组存储在工厂中,这不是实现它的方法。我看到一些地方使用工厂是像 new UsersFactory()
.
尝试使用 APIs 时使用工厂的正确方法是什么?
是否可以使用包含 $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 users = [];
return {
getAllUsers: function() {
return $http.get('users.json').then(
function(result) {
users = result.data;
return users;
},
function(error) {
users = [];
console.log(error);
}
);
},
add: function(user) {
users.push(user);
},
remove: function(user) {
for(var i = 0; i < users.length; i++) {
if(users[i].id === user.id) { // use whatever you want to determine equality
users.splice(i, 1);
return;
}
}
}
};
}]);
通常 add
和 remove
调用是 http
请求(但这不是您在问题中要求的)。如果请求成功,您知道您的 UI 可以 add/remove 视图中的用户。
我喜欢我的 API 工厂到 return 个对象而不是只有一个端点:
app.factory('usersFactory', ['$http', function ($http) {
return {
getAllUsers: getAllUsers,
getUser: getUser,
updateUser: updateUser
};
function getAllUsers() {
return $http.get('users.json');
}
function getUser() {
...
}
function updateUser() {
...
}
}]);
这样,如果您有任何其他与用户相关的端点,您可以在一个工厂中使用它们。另外,我的偏好是 return $http
promise 目录并在控制器中使用 then()
或者你注入工厂的地方。
我真的是route resolve promises的粉丝。这是约翰爸爸的例子。之后我会解释如何将其应用到您正在做的事情中:
// 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;
}
基本上,在你的路线加载之前,你会得到你需要的请求数据(在你的情况下,你的 "users" JSON。)你有几个选择......你可以存储所有Users
工厂中的数据(顺便说一句,你的工厂看起来不错),然后在你的控制器中,只需调用 Users.getAll
,它可以只是 return 用户数组。 或,你可以直接从路由 resolve promise 中传入 users
,就像 John Papa 在他的例子中所做的那样。我不能像他写的文章那样公正,所以我强烈推荐阅读它。恕我直言,这是一种非常优雅的方法。