我根据John Papa's style guide(主要是)重构我的Angular应用程序,并且正在使我的应用程序更加模块化。我遇到了路线问题解决的问题。到目前为止,我使用全局app变量来保存我的Angular应用程序。我的服务也是这样的:
"use strict";
var usersService = app.service("usersService", ["$http", function ($http) {
var userService = {};
var endpoint = ClientSettings.authServiceUrl + "users";
var get = function () {
return $http.get(endpoint);
};
var getUser = function (id) {
return $http.get(endpoint + "/" + id);
};
userService.get = get;
userService.getUser = getUser;
return userService;
}]);
usersService.loadUser = ["usersService", "authService", function(usersService, authService) {
return usersService
.getUser(authService.authentication.id)
.then(function(response) {
return response.data;
});
}];
现在当我尝试重构这个时,我得到了:
(function() {
"use strict";
angular
.module("App.Auth")
.service("usersService", usersService);
usersService.$inject = ["$http"];
function usersService($http) {
var endpoint = ClientSettings.authServiceUrl + "users";
var service = {
get: get,
getUser: getUser
};
return service;
var get = function () {
return $http.get(endpoint);
};
var getUser = function (id) {
return $http.get(endpoint + "/" + id);
};
}
})();
但我遇到usersService.loadUser
的问题。这是一个仅用于解析的函数:
.state("profile", {
url : "/profile",
controller : "profileController",
templateUrl : "profile.html",
resolve : {
user : usersService.loadUser
}
})
UsersService
是Auth
模块的一部分,但路由是在应用程序所在的模块中配置的。
我希望这个模块提供一组用于解析的函数。我的目标是尽量减少代码重复,这肯定会为此做很多事情。
这是基于下面的answer by estus(它是可接受的)。
(function () {
"use strict";
angular
.module("App.Auth")
.provider("usersService", usersServiceProvider);
function usersServiceProvider() {
usersService.$inject = ["$http"];
loadUser.$inject = ["usersService", "authService"];
var provider = {
$get: usersService,
loadUser: loadUser
}
return provider;
function usersService($http) {
var endpoint = ClientSettings.authServiceUrl + "users";
var service = {
get: get,
getUser: getUser
};
return service;
var get = function () {
return $http.get(endpoint);
};
var getUser = function (id) {
return $http.get(endpoint + "/" + id);
};
}
function loadUser(usersService, authService) {
return usersService
.getUser(authService.authentication.id)
.then(function (response) {
return response.data;
});
}
}
})();
注意:如果您正在使用
ngAnnotate
,则必须为注射功能手动指定/*@ngInject*/
(在这种情况下为loadUser
),因为它似乎不会认识到它。至少在撰写本文时。
然后,您将provider
注入config
函数并访问您的resolve
就绪函数,如下所示:
.state("profile", {
url : "/profile",
controller : "profileController",
templateUrl : "profile.html",
resolve : {
user : usersServiceProvider.loadUser
}
})
这是有效的,因为虽然service
在config
时无法使用resolve
,但在解析resolve
时它们仍可用。
只要它是usersServiceProvider
,provider
中就不需要config
- 就绪函数。这是因为它是enum State{A(0),B(1)}
阶段可用的唯一可注射类型的提供者。我是这样做的,因为它允许我将相关功能保存在同一个地方。
答案 0 :(得分:1)
出于实际原因,在单个服务中持有解析器方法是不好的。状态在config
中定义,其中没有注入usersService
,即resolve
进行服务注入。所以上面的代码可以用这个
resolve : {
user : function (usersService, $injector) {
return $injector(usersService.loadUser);
}
}
看起来重构是错误的。
但是,这可以通过usersService
provider
服务来避免,因此usersServiceProvider
可以注入config
,usersServiceProvider.loadUser
可以用作解析器。
我的目标是尽量减少代码重复,这肯定会做到 很多。
通过在usersService
中执行常规作业并将解析器保留在单独的服务中来最小化它。将loadUser
打包到usersService
中没有任何好处(更像是相反)。