2015-06-09 17 views
6

Tôi đang cố gắng viết một nhà máy hiển thị API người dùng đơn giản. Tôi mới đến AngularJS và tôi hơi bối rối về các nhà máy và cách sử dụng chúng. Tôi đã thấy các chủ đề khác nhưng không có chủ đề nào phù hợp với trường hợp sử dụng của tôi.Sử dụng nhà máy để lộ một API đơn giản

Vì mục đích đơn giản, chức năng duy nhất tôi muốn đạt được là nhận tất cả người dùng trong một mảng và sau đó chuyển chúng đến bộ điều khiển thông qua nhà máy được tiêm.

tôi lưu trữ cho người sử dụng trong một file json (bây giờ tôi chỉ muốn đọc tập tin đó, mà không sửa đổi dữ liệu)

users.json:

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

Nhà máy tôi cố gắng để viết nên một cái gì đó như thế này:

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

Và cuối cùng, cuộc gọi điều khiển sẽ là như thế này:

UsersController

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

Tôi đã tìm kiếm trên web và nó có vẻ như nó không phải là thực sự là một thực hành tốt để sử dụng các nhà máy này và nếu tôi muốn đạt được một số chức năng khác như thêm/xóa người dùng mới vào/từ nguồn dữ liệu, hoặc bằng cách nào đó lưu trữ mảng trong nhà máy, đó sẽ không phải là cách để thực hiện. Tôi đã nhìn thấy một số nơi mà việc sử dụng của nhà máy là một cái gì đó giống như new UsersFactory().

Cách chính xác để sử dụng các nhà máy khi cố gắng sử dụng API là gì?

Có thể khởi tạo nhà máy với đối tượng có chứa kết quả $http.get() và sau đó sử dụng nó từ bộ điều khiển theo cách này không?

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

Tôi đã luôn luôn tiêu thụ api bằng cách sử dụng '$ resource', mà có rất nhiều công việc cho bạn khi giao dịch với apis an toàn. nhưng, trong trường hợp của bạn, một http đơn giản nên được tốt vì bạn chỉ làm việc với một tập tin json đơn giản. bạn không tiêu thụ api. –

+0

Bạn có đang thực hiện nhiều cuộc gọi 'getAllUsers()' hay chỉ là một cuộc gọi cho toàn bộ thời gian của ứng dụng của bạn? – allienx

+0

@KevinB Tôi đang sử dụng json đơn giản chỉ để đơn giản, việc sử dụng thực tế của ứng dụng này sẽ được với một API RESTful, nhưng từ quan điểm của khách hàng nó không nên thực sự quan trọng. –

Trả lời

2

tôi không thấy bất cứ điều gì sai trái với nhà máy của bạn. Nếu tôi hiểu chính xác bạn muốn thêm chức năng. Một vài thay đổi nhỏ sẽ làm cho điều này có thể xảy ra.Đây là những gì tôi muốn làm (lưu ý gọi getAllUsers lau ra bất kỳ thay đổi):

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

Điển hình addremove cuộc gọi sẽ http yêu cầu (nhưng đó không phải là những gì bạn đang yêu cầu cho trong câu hỏi). Nếu yêu cầu thành công, bạn biết rằng giao diện người dùng của bạn có thể thêm/xóa người dùng khỏi chế độ xem.

+0

Cảm ơn câu trả lời, có cách nào để khởi tạo đối tượng được trả về với dữ liệu được tiêu thụ bởi '$ http.get()', và chỉ sử dụng các hàm 'add()' và 'remove()'? –

+0

Bây giờ bạn đang nhận được vào 'giải quyết'. Bạn có sử dụng ngRoute hoặc AngularUI Router? –

+0

Tôi đang sử dụng Bộ định tuyến AngularUI. –

0

Tôi thường sử dụng một cái gì đó nhà máy như thế này:

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

    }]) 

nào bạn có thể gọi với:

usersFactory.query(); 

Vì đây là một lời hứa bạn vẫn có thể sử dụng phương pháp .Sau đó với nó quá

+0

Tôi thực sự khuyên bạn nên chạy qua hướng dẫn này: [góc nhìn] (https://docs.angularjs.org/tutorial/step_00) –

0

$ http là một lời hứa đó có nghĩa là bạn phải kiểm tra xem cuộc gọi get bạn làm việc hay không.

vì vậy hãy thử để thực hiện kiểu kiến ​​trúc trong điều khiển của bạn

$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

Tôi thích nhà máy API của tôi để trở về đối tượng thay vì chỉ có một thiết bị đầu cuối:

app.factory('usersFactory', ['$http', function ($http) { 
    return { 
    getAllUsers: getAllUsers, 
    getUser: getUser, 
    updateUser: updateUser 
    }; 

    function getAllUsers() { 
    return $http.get('users.json'); 
    } 

    function getUser() { 
    ... 
    } 

    function updateUser() { 
    ... 
    } 
}]); 

cách đó, nếu bạn có bất cứ điểm cuối sử dụng liên quan khác mà bạn có thể tiêu thụ chúng tất cả trong một nhà máy. Ngoài ra, sở thích của tôi là chỉ cần trả lại thư mục lời hứa $http và tiêu thụ then() trong bộ điều khiển hoặc nơi bạn đang tiêm nhà máy.

1

Tôi thực sự là người hâm mộ của route resolve promises. Đây là ví dụ của John Papa. Tôi sẽ giải thích sau đó làm thế nào để áp dụng điều này với những gì bạn đang thực hiện: (. Trong trường hợp của bạn, bạn "sử dụng" 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; 
} 

Về cơ bản, trước khi tải tuyến đường của bạn, bạn sẽ có được các dữ liệu yêu cầu bạn cần Bạn có một số tùy chọn từ đây ... Bạn có thể lưu trữ tất cả dữ liệu đó trong một nhà máy Users (bằng cách này, nhà máy của bạn có vẻ tốt), và sau đó trong bộ điều khiển của bạn, chỉ cần gọi Users.getAll, mà chỉ có thể trả về mảng người dùng. Hoặc, bạn chỉ có thể vượt qua trong userstừ tuyến đường giải quyết lời hứa, giống như John Papa làm trong ví dụ của mình. Tôi không thể làm điều đó nhiều như công lý như bài viết ông viết, vì vậy tôi nghiêm túc khuyên bạn nên đọc nó. Đó là một cách tiếp cận rất thanh lịch, IMHO.

+0

bạn có thể nhận được một số thời gian chờ đợi không tốt giữa một người dùng thay đổi tiểu bang (thông qua liên kết nhấp hoặc một số nút kích hoạt một sự thay đổi trạng thái) và thực sự được gửi đến trạng thái mới. imo một trải nghiệm người dùng tốt hơn là chuyển chúng sang trạng thái mới ngay lập tức và yêu cầu trình điều khiển tìm nạp dữ liệu và sau đó hiển thị dữ liệu khi nó sẵn sàng. – JesseDahl

Các vấn đề liên quan