1

我想構建一個角度應用程序,主要用作顯示數據,但採用稍微動態的方式。我有多個JSON文件,具有相同的結構,但不同的內容,每個語言:AngularJS:具有異步請求的多個依賴服務

res/information_en.json 

[ 
    { 
     "name": "Jobs", 
     "data": [ 
      { 
       "title": "Title", 
       "employer": "Employer", 
       "description": "Description", 
       "begin": "2015-12", 
       "end": "2016-12" 
      } 
     ] 
    },{ 
     "name": "Personal", 
     "data": [ 
      { 
       "firstname": "Christian", 
       "lastname": "Steinmeyer" 
      } 
     ] 
    } 
] 

德語版:

res/information_de.json 

[ 
    { 
     "name": "Jobs", 
     "data": [ 
      { 
       "title": "Titel", 
       "employer": "Arbeitgeber", 
       "description": "Beschreibung", 
       "begin": "2015-12", 
       "end": "2016-12" 
      } 
     ] 
    },{ 
     "name": "Personal", 
     "data": [ 
      { 
       "firstname": "Christian", 
       "lastname": "Steinmeyer" 
      } 
     ] 
    } 
] 

此外,我還有一個JSON文件,即保持跟蹤所有語言:

res/languages.json 

[ 
    { 
     "name": "English", 
     "short": "en", 
     "active": true 
    },{ 
     "name": "Deutsch", 
     "short": "de", 
     "active": false 
    } 
] 

我想要什麼,本質上,是用戶能夠選擇語言,應該顯示的信息中,從可用的,由給出。爲此,我創建了第一個服務:

app/services/language-service.js 

(function(){ 
    'use strict'; 

    angular.module('gulpAngularCv').factory('LanguageService', LanguageService); 

    /** @ngInject */ 
    function LanguageService($log, $q, $resource, toastr) { 

    var service = {}; 

    service.getLanguages = getLanguages; 

    service.select = select; 

    service.getActiveLanguage = getActiveLanguage; 




    var initialized = false; 

    var languages = []; 

    function getLanguages(){ 
     if (initialized){ 
      return languages; 
     } else { 
      initialize().then(
       function success(result){ 
        angular.forEach(result, function addLanguage(language){ 
         languages.push(language); 
        }) 
        initialized = true; 
       }, function fail(reject){ 
        $log.error("Loading 'res/languages.json' failed."); 
        $log.error(reject); 
        toastr.error('Make sure, it is formatted correctly.', 'Loading language file failed!'); 

       } 
      ); 
      return languages; 
     } 
    } 

    function initialize(){ 
     var deferred = $q.defer(); 
     $resource('res/languages.json').query(
      function success(result){ 
       deferred.resolve(result); 
      }, function fail(reject){ 
       deferred.reject(reject); 
      } 
     ); 
     return deferred.promise; 
    } 

    function select(language){ 
     // iterate over all languages 
     // deactivate, if active and activate if equal to parameter 
    } 

    function getActiveLanguage(){ 
     for (var i = 0; i < languages.length; i++){ 
      if (languages[i].active){ 
       return languages[i]; 
      } 
     } 
    } 

    return service; 

    } 
})(); 

從控制器調用時,它本身就像魅力一樣工作。但正如我所說的,我也希望能夠從相應的json文件中加載信息。我嘗試下一個服務:

app/services/information-service.js 

(function(){ 
    'use strict'; 

    angular.module('gulpAngularCv').factory('InformationService', InformationService); 

    /** @ngInject */ 
    function InformationService($log, $q, $resource, toastr, LanguageService) { 

    var service = {}; 

    service.getInformation = getInformation; 




    var initialized = {}; 

    var information = []; 

    function getInformation(){ 
     var language = LanguageService.getActiveLanguage(); 
     if (initialized === language){ 
      return information; 
     } else { 
      initialize(language).then(
       function success(result){ 
        angular.forEach(result, function addInformation(information){ 
         information.push(information); 
        }) 
        initialized = language; 
       }, function fail(reject){ 
        $log.error("Loading 'res/information_" + language.short + ".json' failed."); 
        $log.error(reject); 
        toastr.error('Make sure, it is formatted correctly.', 'Loading information file failed!'); 

       } 
      ); 
      return information; 
     } 
    } 

    function initialize(language){ 
     var deferred = $q.defer(); 
     $resource("res/information_" + language.short + ".json").query(
      function success(result){ 
       deferred.resolve(result); 
      }, function fail(reject){ 
       deferred.reject(reject); 
      } 
     ); 
     return deferred.promise; 
    } 

    return service; 

    } 
})(); 

我,基本上做同樣的事情,但這個時候,它不會工作,因爲它看起來,這項服務首先注入,即使它依賴於其他一。我碰到下面的錯誤在我的瀏覽器的控制檯:

TypeError: Cannot read property 'short' of undefined 
    at initialize (http://localhost:3000/app/services/information-service.js:44:48) 
    at Object.getInformation (http://localhost:3000/app/services/information-service.js:25:13) 
    at new MainController (http://localhost:3000/app/main/main-controller.js:12:40) 
    at invoke (http://localhost:3000/bower_components/angular/angular.js:4535:17) 
    at Object.instantiate (http://localhost:3000/bower_components/angular/angular.js:4543:27) 
    at http://localhost:3000/bower_components/angular/angular.js:9395:28 
    at link (http://localhost:3000/bower_components/angular-route/angular-route.js:977:26) 
    at invokeLinkFn (http://localhost:3000/bower_components/angular/angular.js:9039:9) 
    at nodeLinkFn (http://localhost:3000/bower_components/angular/angular.js:8533:11) 
    at compositeLinkFn (http://localhost:3000/bower_components/angular/angular.js:7929:13) <div ng-view="" class="ng-scope"> 

在我看來,這個錯誤是奇怪的,因爲承諾應該已經得到解決,通過呼叫的時候,我的方式來實現它。

對於誠信的緣故,這裏的MainController還有:

app/main/main-controller.js 

(function() { 
    'use strict'; 

    angular 
    .module('gulpAngularCv') 
    .controller('MainController', MainController); 

    /** @ngInject */ 
    function MainController(InformationService) { 
    var vm = this; 

    vm.categories = InformationService.getInformation(); 
    } 
})(); 

我已經看了thisthis問題已經,以及官方文檔,但他們只讓我至今..

回答

0

畢竟,我相信我的問題的原因是JavaScript中的可見性和範圍。在信息服務(在問題中發佈)中,我使用名稱爲information的「全局」變量,但在getInformation()方法的每個循環的角度內,我創建了一個具有相同名稱的局部變量,按照我的意願添加到我的原始變量中。爲了完成,我將再次添加兩個服務的最終實現。請注意,我不僅解決了該錯誤,還在信息服務中進行了一些重構(下文)。正如我打算的那樣,此解決方案有效。

app/services/language-service.js 

(function(){ 
    'use strict'; 

    angular.module('gulpAngularCv').factory('LanguageService', LanguageService); 

    /** @ngInject */ 
    function LanguageService($log, $q, $resource, toastr) { 

    var service = {}; 

    service.getLanguages = getLanguages; 

    service.select = select; 

    service.getActiveLanguage = getActiveLanguage; 




    var initialized = false; 

    var languages = []; 

    function getLanguages(){ 
     if (initialized){ 
      return languages; 
     } else { 
      initialize().then(
       function success(result){ 
        $log.debug("Loaded languages from 'res/languages.json'"); 
        $log.debug(result); 
        angular.forEach(result, function addLanguage(language){ 
         $log.debug(language); 
         languages.push(language); 
        }) 
        initialized = true; 
       }, function fail(reject){ 
        $log.error("Loading 'res/languages.json' failed."); 
        $log.error(reject); 
        toastr.error('Make sure, it is formatted correctly.', 'Loading language file failed!'); 

       } 
      ); 
      return languages; 
     } 
    } 

    function initialize(){ 
     var deferred = $q.defer(); 
     $resource('res/languages.json').query(
      function success(result){ 
       deferred.resolve(result); 
      }, function fail(reject){ 
       deferred.reject(reject); 
      } 
     ); 
     return deferred.promise; 
    } 

    function select(language){ 
     // iterate over all languages 
     // deactivate, if active and activate if equal to parameter 
    } 

    function getActiveLanguage(){ 
     for (var i = 0; i < languages.length; i++){ 
      if (languages[i].active){ 
       return languages[i]; 
      } 
     } 
    } 

    return service; 

    } 
})(); 

和信息服務:

app/services/information-service.js 

(function(){ 
    'use strict'; 

    angular.module('gulpAngularCv').factory('InformationService', InformationService); 

    /** @ngInject */ 
    function InformationService($log, $q, $resource, $rootScope, toastr, LanguageService) { 

    var service = {}; 

    service.getCategories = getCategories; 


    var model = {}; 
    model.initialized = null; 
    model.categories = []; 

    function getCategories(){ 
     $log.debug("getCategories"); 
     loadData(); 
     return model.categories; 
    } 

    function loadData(){ 
     var language = LanguageService.getActiveLanguage(); 
     if (language && model.initialized !== language){ 
      initialize(language).then(
       function success(data){ 
        model.categories.length = 0; 
        angular.forEach(data.categories, function addInformation(datum){ 
         $log.debug(datum); 
         model.categories.push(datum); 
        }) 
       }, function fail(reject){ 
        toastr.error('Make sure, it is formatted correctly.', 'Loading information file failed!'); 
       } 
      ); 
     } 
    } 

    function initialize(language){ 
     var deferred = $q.defer(); 
     $resource("res/information_" + language.short + ".json").get(
      function success(result){ 
       deferred.resolve(result); 
       model.initialized = language; 
      }, function fail(reject){ 
       deferred.reject(reject); 
      } 
     ); 
     return deferred.promise; 
    } 

    return service; 

    } 
})();