【问题标题】:JavaScript revealing module pattern public variable not updatingJavaScript 揭示模块模式公共变量未更新
【发布时间】:2014-02-13 21:45:12
【问题描述】:

我正在使用带有显示模块模式的 Angular 服务。该服务在内部从 Web 服务中提取字符串资源,并通过“字符串”公共变量使它们可用。我必须初始化私有的“字符串”变量,因为它是在进行服务调用之前被引用的。

我从服务中获取正确的字符串数据并将其复制到私有“字符串”变量中。但是,当客户端引用公共“字符串”时,它仍然保留其原始值。

知道我做错了什么,或者如何让公共“字符串”更新?

'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
    }
}]);

服务调用将返回的数据设置为私有“字符串”变量

promise.then(function (data) {
            strings = data;
            deferred.resolve();
        },

私有“字符串”现在显示以下内容(通过 Chrome 开发者工具):

strings = {
       'ERROR_HEADER': 'Error!'
       'INVALID_PROCESS_ORDER': 'Process Order [%d] could not be entered because it does not belong to Manfacturing Order [%d]',
       'DUPLICATE_PROCESS_ORDER': 'Process Order [%d] already entered.',
       'USER_NOT_ITAR': 'Manufacturing order [%d] is ITAR, and you are not ITAR approved.  You cannot proceed with this order.  Please contact your supervisor.'
   };

然而,当在 Angular 控制器中引用公共“字符串”时,“字符串”仍在引用私有“字符串”的原始值。

Resource.Strings:

{
   'ERROR_HEADER': 'Error!'
};

有什么建议吗?

【问题讨论】:

    标签: javascript angularjs revealing-module-pattern


    【解决方案1】:

    您将用data 完全替换strings 变量。它们是不同的对象并且具有不同的引用,因此任何引用了之前的strings 对象的客户端代码都不会看到更改。

    您可以扩充现有的 strings 对象,而不是替换。

    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();
    },
    

    【讨论】:

    • 感谢 voithos...确实解决了问题。我一直在以类似的方式使用存储库,并没有遇到这个明显的参考与价值问题......我需要阅读更多关于这个的信息。
    【解决方案2】:

    您从工厂方法返回的 JavaScript 对象永远不会使用新的字符串对象进行更新。您需要保留对它的引用才能更新“公共视图”:

    service = {
        Strings: strings,
        GetStringResources: getStringResources
    };
    return service;
    

    然后更新您的 .then 回调以更新私有变量和公共服务对象:

    .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;
    }]);
    

    【讨论】:

    • 谢谢squid314..有趣...我也会试试这个方法。
    • 没问题。正如@voithos 所说,这是一个参考与价值的问题。基本上,您有 2 个指向相同值的指针(或引用),而您只将其中 1 个更新为新值(特别是私有值)。
    猜你喜欢
    • 2012-02-12
    • 1970-01-01
    • 1970-01-01
    • 2013-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多