仍然对angularjs服务和工厂感到困惑
我已经阅读了几个关于angularjs服务和工厂的主题。 我明白,服务是单身人士,工厂返回对象的实例。 但我仍然不太明白如何使用它们。 我的应用是一个简单的社交网络。 使用该应用程序的人需要登录,然后他们才能查看其他成员并向他们发送消息。
我的理想设计是:
我创建了以下内容:
angular.module('myapp.models', [])
.factory('Member', ['$log', 'DataService', '$http', 'Restangular',
function($log, DataService, $http, Restangular) {
return {
user_id: null,
first_name: null,
last_name: null,
authenticate: function(username, password, loginSuccessHandler, loginErrorHandler) {
$log.debug("inside Member.authenticate");
var authSuccessHandler = function(data, status, headers, config) {
$http.defaults.headers.common.Authorization = 'Basic ' + btoa(data._id + ':' + data.token);
var token = btoa(data._id + ':' + data.token);
user_id = data._id; // attach this to the rootScope? Needs to be
// globally accessible (or even this whole object)
Restangular.setDefaultHeaders({'Authorization': 'Basic ' + token});
$log.debug("Auth successful, token stored " + token);
loginSuccessHandler();
};
DataService.authenticate(username, password, authSuccessHandler, authErrorHandler);
},
...
我怎样才能实例化它,并使其可用于其他范围(例如,在其他范围我会知道登录的用户的ID)?
另外,当我解析一列成员时,我怎么能实例化这个对象? 例如,如果我有一个对象{first_name: "John", last_name: "Smith"}
我怎么能从这个工厂获得一个成员对象,并设置这些属性?
factory
和service
都是provider
抽象。
这是angular用来实例化新提供者的方法:
function provider(name, provider_) {
if (isFunction(provider_) || isArray(provider_)) {
provider_ = providerInjector.instantiate(provider_);
}
if (!provider_.$get) {
throw Error('Provider ' + name + ' must define $get factory method.');
}
return providerCache[name + providerSuffix] = provider_;
}
第一部分在角度应用程序加载时实例化一个新的(单例)对象。 $get
方法用作新对象的构造函数。 这是一个provider
的实例化可能看起来像(从角度的文档):
myApp.provider('unicornLauncher', function UnicornLauncherProvider() {
var useTinfoilShielding = false;
this.useTinfoilShielding = function(value) {
useTinfoilShielding = !!value;
};
this.$get = ["apiToken", function unicornLauncherFactory(apiToken) {
// let's assume that the UnicornLauncher constructor was also changed to
// accept and use the useTinfoilShielding argument
return new UnicornLauncher(apiToken, useTinfoilShielding);
}];
});
以下是配置提供者的方法。 在module.config()
块中,与稍后我们将提供者注入到控制器/指令/服务时不同,我们获取单例,而不是$get
方法的返回值。
myApp.config(["unicornLauncherProvider", function(unicornLauncherProvider) {
unicornLauncherProvider.useTinfoilShielding(true);
}]);
然后,无论何时注入并调用unicornLauncher
, $get
方法中的内容都会被调用,并且您将获得一个带有提供的配置的新UnicornLauncher
,在这种情况下, useTinfoilShielding = true
。
正如你所看到的,提供者有两部分。 首先,它是一个单例,在角度加载时实例化和配置,并推送到providerCache
,以便您可以在整个应用程序中使用它。 它还有一个用于实例化新对象的$get
方法。
你可以这样看待它:单身人士将它的属性和方法作为你在加载应用时设置的设置和数据,然后你可以创建使用这些设置和数据的新对象。
如果您为其他人创建了一个模块供其使用,那么需要单独修改每个应用程序的选项,这就是您将要这样做的方式。 您可以将提供程序注入您的应用程序,对其进行配置,然后根据需要随时提供对象,并使用我们在配置提供程序时设置的预设。
然后我们有服务和工厂 。 这些实际上是对provider
抽象。 以下是角度用于启动factory
:
function factory(name, factoryFn) {
return provider(name, { $get: factoryFn });
}
它只是一个provider
,而不是返回一个包含我们所看到的所有属性的对象,它只返回一个带有$get
方法的对象,并且没有像provider
那样的其他任何可变部分。
这是service
的功能:
function service(name, constructor) {
return factory(name, ['$injector', function($injector) {
return $injector.instantiate(constructor);
}]);
}
这里我们有一个工厂,它的$get
方法使用提供的构造函数返回一个由angular实例化的单例。 所以你有一个你可以在整个应用程序中使用的单例,你可以在任何地方使用它的方法。 你可以在一个地方设置它的属性,并看到你在应用程序的其他地方设置的相同值,因为无论你注入哪个对象,它都是相同的单例对象。
总结 :
主要区别在于service
是一个对象,它是在您声明服务时由您提供的构造函数创建的,而factory
仅仅是一个可用于创建新对象的函数,就像您在本地JavaScript中一样。
希望有助于了解factory
和service
。
回到你的问题。
在你的情况下,你有一个你想用来为每个成员创建一个新对象的工厂。 在注册Member
的控制器中,您可以简单地执行以下操作:
var data = {first_name: "John", last_name: "Smith"}
var member = new Member(data);
对工厂进行小改动:
.factory('Member', ['$log', 'DataService', '$http', 'Restangular',
function($log, DataService, $http, Restangular) {
return function(data) {
//construct the object
}
])
对工厂的new
调用(作为构造函数注入)将返回一个新的,唯一的对象,与JS中的其他对象一样构造。 你可以随心所欲地做任何事情。 您可以将其保留在控制器, $rootScope
中或保存成员和其他相关数据和功能的服务中。 然后,您可以在整个应用程序中随时随地注入该服务。
我只想说服务和工厂以及提供者都是单身人士。
其余的检查这些答案:AngularJS:服务vs提供者vs工厂
链接地址: http://www.djcxy.com/p/13631.html