JavaScript模块模式公共变量未更新
我使用的是带显示模块模式的角度服务。该服务从web服务内部提取字符串资源,并通过“Strings”公共变量使其可用。我必须初始化私有“strings”变量,因为它在服务调用之前被引用 我从服务获取正确的字符串数据,并将其复制到私有“strings”变量。但是,当客户端引用公共“字符串”时,它仍然保留其原始值 你知道我做错了什么,或者如何更新公共“字符串”吗JavaScript模块模式公共变量未更新,javascript,angularjs,revealing-module-pattern,Javascript,Angularjs,Revealing Module Pattern,我使用的是带显示模块模式的角度服务。该服务从web服务内部提取字符串资源,并通过“Strings”公共变量使其可用。我必须初始化私有“strings”变量,因为它在服务调用之前被引用 我从服务获取正确的字符串数据,并将其复制到私有“strings”变量。但是,当客户端引用公共“字符串”时,它仍然保留其原始值 你知道我做错了什么,或者如何更新公共“字符串”吗 'use strict'; io1App.factory('Resources', ['$rootScope', 'DataService
'use strict';
io1App.factory('Resources', ['$rootScope', 'DataService', '$q',
function ($rootScope, DataService, $q) {
var urlBase = '/api/sfc/resource';
// Need to pre-define 'ERROR_HEADER', since it is referenced in Index.html...before we have a chance to download it from the server.
var strings = {
'ERROR_HEADER': 'Error!'
};
var getStringResources = function (locale) {
var url = urlBase + '/' + locale;
var deferred = $q.defer();
var promise = DataService.GetMethod(url);
// Note that DataService.GetMethod(...) is returning a $q promise
promise.then(function (data) {
strings = data;
deferred.resolve();
},
function (err) {
deferred.reject(err);
});
return deferred.promise;
};
return {
Strings: strings,
GetStringResources: getStringResources
}
}]);
服务调用将返回的数据设置为私有“strings”变量
promise.then(function (data) {
strings = data;
deferred.resolve();
},
私有“字符串”现在显示以下内容(通过Chrome开发者工具):
然而,当在角度控制器中引用公共“字符串”时,“字符串”仍然引用私有“字符串”的原始值
资源.字符串:
{
'ERROR_HEADER': 'Error!'
};
有什么建议吗?您正在将
字符串
变量完全替换为数据
。它们是不同的对象,具有不同的引用,因此任何引用了以前的字符串的客户端代码都不会看到更改
您可以扩充现有的字符串
对象,而不是替换
promise.then(function (data) {
// Merge properties into `strings`
// You could also use any other "extension" technique, e.g. _.extend()
for (var k in data) {
if (data.hasOwnProperty(k)) {
strings[k] = data[k];
}
}
deferred.resolve();
},
从工厂方法返回的JavaScript对象永远不会用新的字符串对象更新。您需要保留对它的引用才能更新“公共视图”:
然后更新。然后
回调以更新私有变量和公共服务对象:
.then(function(data) {
strings = service.strings = data;
deferred.resolve(data); // don't need to resolve this with the strings, but why not?
}, function error(){...});
但是,由于您不再真正拥有“私有数据”(仅对公共变量的私有引用),因此您根本不需要拥有私有字符串变量:
io1App.factory('Resources', ['$rootScope', 'DataService', '$q',
function ($rootScope, DataService, $q) {
var urlBase = '/api/sfc/resource';
var service = {
// Need to pre-define 'ERROR_HEADER', since it is referenced in Index.html...before we have a chance to download it from the server.
Strings: { 'ERROR_HEADER': 'Error!' },
GetStringResources: function (locale) {
var url = urlBase + '/' + locale;
var deferred = $q.defer();
var promise = DataService.GetMethod(url);
// Note that DataService.GetMethod(...) is returning a $q promise
promise.then(function (data) {
service.strings = data;
deferred.resolve(data); // don't need to resolve this with the strings, but why not?
},
function (err) {
deferred.reject(err);
});
return deferred.promise;
};
return service;
}]);
谢谢voithos…这确实解决了问题。我一直在以类似的方式使用存储库,并没有遇到这种明显的参考与价值问题…我需要更多地了解这一点。谢谢squid314…有趣…我也会尝试这种方法。没问题。正如@voithos所说,这是一个参考与价值的问题。基本上,您有两个指向同一个值的指针(或引用),您只将其中的一个更新为新值(特别是私有值)。
.then(function(data) {
strings = service.strings = data;
deferred.resolve(data); // don't need to resolve this with the strings, but why not?
}, function error(){...});
io1App.factory('Resources', ['$rootScope', 'DataService', '$q',
function ($rootScope, DataService, $q) {
var urlBase = '/api/sfc/resource';
var service = {
// Need to pre-define 'ERROR_HEADER', since it is referenced in Index.html...before we have a chance to download it from the server.
Strings: { 'ERROR_HEADER': 'Error!' },
GetStringResources: function (locale) {
var url = urlBase + '/' + locale;
var deferred = $q.defer();
var promise = DataService.GetMethod(url);
// Note that DataService.GetMethod(...) is returning a $q promise
promise.then(function (data) {
service.strings = data;
deferred.resolve(data); // don't need to resolve this with the strings, but why not?
},
function (err) {
deferred.reject(err);
});
return deferred.promise;
};
return service;
}]);