AngularJS shared REST service between modules and

2019-09-01 10:06发布

问题:

I need to have a set of resource factories to consume a rest api and use that in all of my modules and controllers. I'm confused as to how this should be separated and how to access the factories from controller.

As an example, let's assume I have:

// rest.js
angular.module('myApp.rest', ['ngResource'] )
    .factory('Book', function ($resource) {
        return $resource('api/book', {}, {
            getBook: {
                method: 'GET'
            },
        });
    })

Here's the main module as myApp:

 // app.js
 angular.module('myApp', [

        'ngRoute',
        'ngResource',

        'app.rest',
        'app.library'

    ])
      .config(['$routeProvider', function ($routeProvider) {
            $routeProvider.
                when('/book', {
                    templateUrl: 'someTemplate',
                    controller: 'LibraryCTRL',
                });

Now I want to have another module called app.library which can use Book resource. How the Dependency Injection would look like?

More important question: Is this the right way to do it? I mean is it better to attach the whole Book factory to myApp or use a separate myApp.rest module?

// library.js
angular
    .module('myApp.library', ['ngResource']) // INJECT REST MODULE HERE?
    .controller('LibraryCtrl', Library);

// INJECT BOOK RESOURCE HERE? 
Library.$inject = [];

// USE BOOK IN THIS CONSTRUCTOR
function Library() {

    var vm = this;

    // USING IT
    Book.getBook(function(data){
         vm.book = data;
    });
}

回答1:

let's Abstract the problem

as i understand you want to make custom factory "service" which can be used in all modules and controllers that is responsible for consuming rest api

so you will have serviceModule.js

var ServiceApp = angular.module('ServiceApp', []);
ServiceApp
        .factory(
                'restControllerService',
                [
                        '$http',
                        function($http) {

                            var doRequest = 
                            function(URL) {
                                    return $http({
                                        method : 'get',
                                        url :  URL, 
                                       headers : {
                                       'Content-Type' :'application/json'
                                                 }
                                    });
                                    });
                                }

                            }
                            return {
                                getBook : function() {
                                    return doRequest('api/book');
                                }
                            };
                        } ]);

you can inject that in any other module like that

var library = angular.module('libraryModule', [ "ServiceApp" ]);
libraryModule.controller('LibraryCtrl', [
        '$scope',
        'restControllerService',
        function($scope,restControllerService) {

            $scope.book = null;

            $scope.getbook = function() {

                    restControllerService.getbook('api/book').success(
                            function(data) {
                                $scope.book = data;
                            }).error(function() {
                        $scope.book = null;
                    });
                }
            };      


回答2:

I believe you're trying to do this: myApp --> myApp.library --> myApp.rest

You're pretty much there. Just make myApp.library inject the myApp.rest module.

angular
    .module('myApp.library', ['myApp.rest'])
    .controller('LibraryCtrl', ['Book', function(Book) {
     // use Book.getBook() here.
    }]);

Also remove the dependency of myApp.rest and ngResource from myApp module, since you're not using them there.

angular.module('myApp', [
        'ngRoute',
        'app.library'
    ])

In general, only add a dependency if you're directly using it in that module.

I don't believe there is a best practice for how to separate code into modules. Personally, I like to have a single module for an entire application, unless I'm trying to reuse a piece of code in another application.