Javascript 仍然对angularjs服务和工厂感到困惑
我读过几篇关于angularjs服务和工厂的文章。我知道服务是单例的,工厂返回对象的实例。但我还是不知道如何使用它们。我的应用程序是一个简单的社交网络。使用该应用程序的用户需要登录,然后才能查看其他成员并向他们发送消息 我的理想设计是:Javascript 仍然对angularjs服务和工厂感到困惑,javascript,angularjs,Javascript,Angularjs,我读过几篇关于angularjs服务和工厂的文章。我知道服务是单例的,工厂返回对象的实例。但我还是不知道如何使用它们。我的应用程序是一个简单的社交网络。使用该应用程序的用户需要登录,然后才能查看其他成员并向他们发送消息 我的理想设计是: 创建一个成员对象来表示我的服务的任意成员。每当“list”或“get”操作返回数据时,它都会被包装在这个成员中,这样我就可以对其调用实用程序方法。我会用工厂来做这个 当用户登录到应用程序时,创建一个代表他们的成员(包含他们的用户ID和身份验证令牌,用于将来的身份
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)
另外,在分析成员列表时,如何实例化此对象?例如,如果我有一个对象
{名字:“John”,姓氏:“Smith”}
我如何从这个工厂获得一个设置了这些属性的成员对象?工厂和服务都是提供者的抽象
这是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_;
}
第一部分在angular应用程序加载时实例化一个新的(单例)对象。$get
方法用作新对象的构造函数。这就是提供者的实例化可能的样子(来自angular的文档):
以下是如何配置提供程序。在module.config()
块中,与稍后将提供程序注入控制器/指令/服务时不同,我们得到的是单例,而不是$get
方法的返回值
myApp.config(["unicornLauncherProvider", function(unicornLauncherProvider) {
unicornLauncherProvider.useTinfoilShielding(true);
}]);
然后,每当您注入并调用unicornLauncher
时,$get
方法中的内容都将被调用,并且您将获得一个新的unicornLauncher
,在这种情况下,它具有所提供的配置,useTinfoilShielding=true
如您所见,提供者有两个部分。首先,它是一个单例,在angular加载时进行实例化和配置,并推送到providerCache
,因此您可以在整个应用程序中使用它。它还有一个用于实例化新对象的$get
方法
您可以这样看待它:singleton将其属性和方法作为您在加载应用程序时设置的设置和数据,然后您可以创建使用这些设置和数据的新对象
如果您创建了一个供其他人使用的模块,则需要分别使用每个应用程序的选项对其进行修改,这就是您要做的。你可以将提供者注入到你的应用程序中,对其进行配置,然后让它按照我们在配置提供者时设置的预设,根据你的需要分发对象
然后我们有服务和工厂。这些实际上是提供者
的抽象。以下是angular用于启动工厂的函数:
function factory(name, factoryFn) {
return provider(name, { $get: factoryFn });
}
它只是一个提供程序
,但它并没有返回一个包含我们看到的所有属性的对象,而是返回一个只包含$get
方法的对象,并且没有任何其他可变部分,如提供程序
以下是服务的功能:
function service(name, constructor) {
return factory(name, ['$injector', function($injector) {
return $injector.instantiate(constructor);
}]);
}
这里我们有一个工厂,它的$get
方法使用提供的构造函数返回一个由angular实例化的单例。所以你有一个可以在整个应用程序中使用的单例,你可以在任何地方使用它的方法。你可以在一个地方设置它的属性,并在应用程序的其他地方看到你设置的相同值,因为无论你在哪里注入它,它都是相同的单例对象
摘要:
主要区别在于服务
是angular根据声明服务时提供的构造函数创建的对象,工厂
只是一个可以用来创建新对象的函数,就像在本机JavaScript中一样
希望有助于理解工厂
和服务
回到你的问题上来
在您的例子中,您有一个工厂,您希望使用它为每个成员创建一个新对象。在注入成员的控制器中,您只需执行以下操作:
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
或保存成员和其他相关数据和函数的服务中。然后你可以在整个应用程序的任何地方注入该服务。我只想说服务和工厂以及提供商都是单身
对于其他人,请检查以下答案:我总是说,如果理解某事物的原理如此困难,那么为什么还要尝试使用它呢?谢谢。你的答案加上现场的视频帮助很大。
.factory('Member', ['$log', 'DataService', '$http', 'Restangular',
function($log, DataService, $http, Restangular) {
return function(data) {
//construct the object
}
])