2014-02-13 51 views
1

我使用角服務用顯示模塊圖案。該服務在內部從Web服務中提取字符串資源,並通過「字符串」公共變量使其可用。我必須初始化私有的「字符串」變量,因爲它在服務調用之前被引用。JavaScript的暴露模塊圖案公共變量不更新

我從服務中獲取正確的字符串數據並將其複製到私有的「字符串」變量中。但是,當客戶引用公共「絃樂」時,它仍然保留其原始價值。

任何想法我做錯了什麼,或如何獲得公共「字符串」更新?

'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.' 
    }; 

然而,當在角控制器中引用公共「字符串」時,「字符串」仍然引用私有字符串的原始值。

Resource.Strings:

{ 
    'ERROR_HEADER': 'Error!' 
}; 

有什麼建議?

回答

0

您正在用data完全替代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(); 
}, 
+0

謝謝voithos ......那確實解決了這個問題。我一直以類似的方式使用存儲庫,並沒有遇到這種明顯的參考與價值問題......我需要閱讀更多關於此的信息。 – programmerj

0

從工廠方法返回的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; 
}]); 
+0

感謝squid314 ..有趣...我也會嘗試這種方法。 – programmerj

+0

沒問題。正如@voithos所說,這是一個參考與價值問題。基本上你有2個指針(或引用)到相同的值,你只是將其中的1個更新爲新值(特別是私有值)。 – squid314