在重构一个相当大的项目之前,我真的试图围绕角度的服务/工厂/提供商构造。
我已阅读很多关于服务与工厂的文档和文章,并认为我了解每个文档是如何创建的以及它们的作用。
然而,在尝试尝试的时候,我试图在工厂或两个工厂使用服务......
这非常有用:我现在明白我的“jsonService”中只有一个' (它是一个单身人士),所以这个简单的方法将无法工作......(我需要每个工厂都有一个单独的实例)
.service('jsonService', ['$http', function ($http) {
var data= {'msg':'no data'};
this.serviceData= data;
this.get= function(url){
$http.get(url).then(function (resp) {
data= resp.data;
});
}
}])
.factory('fac1', ['jsonService', function(jsonService){
jsonService.get('json/data1.json');
return jsonService.serviceData;
}])
.factory('fac2', ['jsonService', function(jsonService){
jsonService.get('json/data2.json');
return jsonService;
}])
当我在控制器中使用工厂时:
myController.f1= fac1;
myController.f2= fac2.serviceData;
我可以看到 fac1 和 fac2 都返回相同的对象,它们都有 {msg:&#39;没有数据&#39;} < / em>,如果我改变一个,那么他们都会改变。
我的问题是:
即使我可以打破服务并看到 data = {msg:&#39;没有数据&#39;} 并看到它被设置为响应数据 - 为什么我看不到 fac1 或 fac2 的任何变化?
我能想到的是,某个地方必须有多个 var data ,有些东西不是单身&#39; ????
编辑:我现在尝试过:this.serviceData= function(){return data;};
和
myController.f2= fac2.serviceData(); // this is always the 'no data' object
myController.f3= fac2.serviceData;
如果我(很久以后)打电话:
var something= myController.f3();
然后我得到了json数据......但myController.f2仍然是 {msg:&#39;没有数据&#39;} 为什么?
答案 0 :(得分:1)
好的,在尝试了m.e.conroy的建议之后我终于明白了......
这个问题与angular无关,它是javascript传递对象的方式。 (见:Is JavaScript a pass-by-reference or pass-by-value language?)
工厂传回原始 {msg:'无数据'} 对象的“复制参考”,并最终分配了服务:
data= resp.data;
替换了'数据',但工厂提供的引用仍然是旧对象。
现在,如果我这样做:
.service('jsonService', ['$http', function ($http) {
var data= {'msg':'no data', 'result':null};
this.serviceData= data;
this.get= function(url){
$http.get(url).then(function (resp) {
data.result= resp.data; // update properties of the data object
data.msg='got data!'; // instead of replacing it
});
}
}])
......然后一切都有意义!
myController 中的变量在数据到达时会发生变化(因为我还没有'换出'数据对象)。
显然,我仍有问题,我的两个工厂都会返回同一个对象(我会看看Sacho对此的建议) - 但我想我已经学会了一些非常基本的东西。< / p>
答案 1 :(得分:0)
试试这个:
this.serviceData = function(){
return data;
};
你也可能有种族的情况。在应用程序要求serviceData
答案 2 :(得分:0)
角度的“服务”和“工厂”之间的区别微乎其微 - 我建议只使用其中一个,并坚持使用它。从这一点开始,我将这些元素称为“服务”,即使我只使用angular.factory
来声明它们。
对于您最终想要做的事情,有一个更简单的解决方案 - 只需从您的服务中返回承诺。
this.get= function(url){
return $http.get(url)
}
然后在你的controller / directive /中,只需使用它:
jsonService.get(url).then(function success(response) {
// do things with the response
})
但是您似乎想要使用服务来创建许多实例,所以这是一个人为的例子:
.factory('jsonService', jsonService)
jsonService.$inject = ['$http']
function jsonService($http) {
return Fixed
function Fixed(url) {
this.url = url
this.promise = null
this.get = get.bind(this)
function get() {
// This caches the request so you only do it once, for example
if (this.promise == null) {
this.promise = $http.get(url)
}
return this.promise
}
}
}
然后在你的控制器中,你会做类似的事情:
var fixedOne = new jsonService('fixedOne')
fixedOne.get().then(...)