简体   繁体   中英

In AngularJS what is the cleanest way to declare a factory / service?

What is the proper / cleanest way to implement a factory / service?

I have come across a few different ways of doing this and thought to myself what is actually the best way...

Firstly this method:

(function(){
var github = function($http) {
    var getUser = function(username) {
        return $http.get("https://api.github.com/users/" + username)
            .then(function(response) {
                return response.data;
            });
    };

    var getRepos = function(user) {
        $http.get(user.repos_url)
            .then(function(response) {
                return response.data;
            });
    };

    return {
        getUser: getUser,
        getRepos: getRepos
    };
};
var module = angular.module("githubViewer");
module.factory("github", github);
}());

In a recent tutorial I was reading this was the method used. Note that at the bottom I am adding the factory with a name then the function. The function call contains $http. From my understanding of how (new) angular works with controllers is for minification to work properly you need to pass the $http first as a string then use it as a parameter. Which this method doesn't do.

Next I rewrote it to look like this:

(function(){
var github = function($http) {
    this.getUser = function(username) {
        return $http.get("https://api.github.com/users/" + username)
            .then(function(response) {
                return response.data;
            });
    };

    this.getRepos = function(user) {
        $http.get(user.repos_url)
            .then(function(response) {
                return response.data;
            });
    };

    return {
        getUser: getUser,
        getRepos: getRepos
    };
};
var module = angular.module("githubViewer");
module.factory("github", ["$http", github($http)]);
}());

I added an array of arguments to the factory call. ran the code and it works the same. I am assuming this will allow for minification? (if it even had the problem from before). Is it redundant to add "$http" to the actual function itself "var github = function($http)" ? Because I also removed "$http" to see what would happen and it still ran as expect.

And lastly I tried this:

(function(){
var module = angular.module("githubViewer");
module.factory("github",
    ["$http", function($http) {
        this.getUser = function(username) {
            return $http.get("https://api.github.com/users/" + username)
                .then(function(response) {
                    return response.data;
                });
        };

        this.getRepos = function(user) {
            $http.get(user.repos_url)
                .then(function(response) {
                    return response.data;
                });
        };

        return {
            getUser: getUser,
            getRepos: getRepos
        };
    };
]
}());

This looks the cleanest to me. Instead of passing a labeled function I passed an anonymous function and gave a string to represent it. I ran the code and it worked as expected. I also added the "this" key word instead of declaring a variable as function. With or without "this" it still worked.

Now here is the confusion... whats the best way? Are none of these the best way? I prefer to use this.name = function over var name = function . What is best in that regard? Is it actually more readable to use

module.factory("github"["$http", function($http)

vs

module.factory("github", github);  

or

module.factory("github", ["$http", github($http)]);"

And beyond that, should controllers, services, factories, providers all be declared in the same fashion?

I personally use the following form:

angular.module('myApp').controller('myController', [
    '$scope', '$state', '$http',
    function ($scope, $state, $http) {
        ...
    }
]);

When you declare your services/factories/controllers etc like that, you steer clear of global scope polution, you don't have to wrap you declaration in an anonymous function, plus it allows for minification. And as Joe mentioned in the other answer using array notation is the preferred way.

You mentioned readability in the comments, i, personally am having absolutely no problems with the above and never had any complaints. In some projects i've used another form, because of the amount of dependencies, i put them all on a separate line:

angular.module('myApp').controller('myController', [
    '$scope',
    '$state',
    '$http',
    function ($scope, $state, $http) {
        ...
    }
]);

This way it's very easy to see what gets injected, but harder to compare it to the parameters of the function. But that's a matter of preference.

The way i see it, the less code, the better. Why use an anonymous function if you can do it without? The less code, the more readable it gets. Same thing with declaring a seperate function and assigning that to your definition. To me that gets confusing.

There's a good deal of subjectivity involved in this answer, however angular's DI system always suggests you declare dependencies as illustrated here . As always, there may not be a best way, but there is an Angular Way.

In your specific case scroll to Inline Array Annotation, it clearly states it is the preferred way of declaring services.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM