2015-06-09 29 views
6

我想寫一個公開一個簡單的用戶API的工廠。我是AngularJS的新手,我對工廠以及如何使用它們感到困惑。我看過其他主題,但沒有一個與我的用例很相稱。使用工廠來公開一個簡單的API

爲了簡單起見,我希望實現的唯一功能是獲取數組中的所有用戶,然後通過注入的工廠將它們傳遞給控制器​​。

我存儲在一個JSON文件中的用戶(現在我只想讀取文件,而無需修改數據)

users.json:

[ 
{ 
    "id": 1, 
    "name": "user1", 
    "email": "[email protected]" 
}, 
{ 
    "id": 2, 
    "name": "user2", 
    "email": "[email protected]" 
} 
] 

工廠我試圖寫應該是這樣的:

UsersFactory:

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); 
       } 
      ); 
     } 
    }; 
}]); 

最後,控制器調用會是這樣:

UsersController

app.controller('UsersCtrl', ['$scope', 'usersFactory', function($scope, usersFactory){ 
    usersFactory.getAllUsers().then(function (result) { 
     $scope.users = result; 
    }); 
}]); 

我在網上搜索,它好像它是不是真的用這個工廠的一個很好的做法方式,如果我想要實現更多的功能,比如向數據源添加/刪除新用戶,或者以某種方式將數組存儲在工廠中,那麼這不是辦法。我見過一些地方,工廠的使用類似於new UsersFactory()

嘗試使用API​​時使用工廠的正確方法是什麼?

是否可以使用包含$http.get()結果的對象初始化工廠,然後通過控制器以這種方式使用它?

var usersFactory = new UsersFactory(); // at this point the factory should already contain the data consumed by the API 
usersFactory.someMoreFunctionality(); 
+0

我總是使用'$ resource'來消費api,它在處理寧靜的apis時爲你做了很多工作。但在你的情況下,一個簡單的http應該沒問題,因爲你只是使用一個普通的json文件。你沒有消費api。 –

+0

你打算做多個'getAllUsers()'調用,還是隻是你的應用程序的一次調用? – allienx

+0

@KevinB我只是爲了簡單而使用普通的json,這個應用程序的真正用途是使用RESTful API,但從客戶的角度來看,它應該不是真的重要。 –

回答

2

我看不出有什麼毛病貴廠這種類型的架構。如果我理解正確,你想添加功能。一些小的改變會使這成爲可能。這裏就是我會做(請注意,調用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; 
       } 
      } 
     } 
    }; 
}]); 

通常情況下,addremove接聽的話會有http請求(但不是你的問題,問什麼)。如果請求成功,您知道您的用戶界面可以在視圖中添加/刪除用戶。

+0

感謝您的回答,有沒有一種方法來初始化返回的對象與數據消耗的'$ http.get()',只需使用'add()'和'remove()'函數? –

+0

現在你正在進入'決心'。你使用ngRoute還是AngularUI路由器? –

+0

我正在使用AngularUI路由器。 –

0

我通常使用一個工廠是這樣的:

.factory('usersFactory', ['$resource', 
    function($resource){ 
    return $resource('http://someresource.com/users.json', {}, { 
     query: { 
      method:'GET', 
      isArray:true 
      } 
     }) 

    }]) 

,你可以調用具有:

usersFactory.query(); 

由於這是一個承諾,你仍然可以使用。於是法它也是

+0

我真的建議運行這個教程:[angular](https://docs.angularjs.org/tutorial/step_00) –

0

$ http是一個承諾,這意味着你必須檢查你的電話是否有效。

所以要儘量實現在控制器

$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 
    }); 
1

我喜歡我的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承諾目錄,並在控制器中使用then(),或者在您注入工廠的地方。

1

我真的是route resolve promises的粉絲。這是約翰帕帕的例子。我隨後會解釋如何將其應用到你在做什麼:(你的情況,你的「用戶」 JSON)

// 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工廠(順便說一下,您的工廠看起來很好),然後在您的控制器中,只需撥打Users.getAll即可返回用戶陣列。 ,你可以通過users從路線解析諾言,很像約翰帕帕在他的例子。我不能像他寫的那篇文章那麼公正,所以我會認真地推薦閱讀它。這是一個非常優雅的方法,恕我直言。

+0

您可以在用戶更改狀態(通過鏈接單擊或某些按鈕觸發狀態更改)和實際發送到新狀態之間獲得一些ungood等待時間。更好的用戶體驗是立​​即將它們轉換到新狀態,並讓控制器獲取數據,然後在準備就緒時進行渲染。 – JesseDahl