Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用factory公开一个简单的API_Javascript_Angularjs_Factory - Fatal编程技术网

Javascript 使用factory公开一个简单的API

Javascript 使用factory公开一个简单的API,javascript,angularjs,factory,Javascript,Angularjs,Factory,我正在尝试编写一个工厂,它公开一个简单的用户API。我是AngularJS的新手,对工厂和如何使用工厂有点困惑。我见过其他主题,但没有一个与我的用例很匹配 为了简单起见,我想实现的唯一功能是将所有用户放入一个数组中,然后通过注入工厂将它们传递给控制器 我将用户存储在一个json文件中(目前我只想读取该文件,而不想修改数据) users.json: [ { "id": 1, "name": "user1", "email": "a@b.c" }, { "id": 2

我正在尝试编写一个工厂,它公开一个简单的用户API。我是AngularJS的新手,对工厂和如何使用工厂有点困惑。我见过其他主题,但没有一个与我的用例很匹配

为了简单起见,我想实现的唯一功能是将所有用户放入一个数组中,然后通过注入工厂将它们传递给控制器

我将用户存储在一个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);
                }
            );
        }
    };
}]);
我试图写的工厂应该是这样的:

用户工厂:

[
{
    "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路由器。在用户更改状态(通过单击链接或触发状态更改的按钮)和实际被发送到新状态之间,您可以获得一些不好的等待时间。在我看来,更好的用户体验是立即将它们转换到新状态,并让控制器获取数据,然后在数据准备就绪时进行渲染。