2017-07-19 48 views
1

我想在我的控制器裏面加載2個json數據到$ scope中,然後再做一些基本的事情。但是,我的工廠中的$ http返回狀態對象,因爲它返回一個承諾。

我作爲工廠對象

(function(angular) { 
    'use strict'; 
    angular.module('myModule').factory("config", function($http) { 
     return{ 
      getConfig: function() { 
       return $http.get('json/config.json').then(function(response) { 
        return response.data; 
       }); 
      }, 
      getPreferences: function() { 
       return $http.get('json/preferences.json').then(function(response) { 
        return response.data; 
       }); 
      } 
     }; 
    }); 
})(window.angular); 

如何從$範圍變量的幾個文件我的主控制器內的所有我的外部JSON數據存儲沒有超時或添加幾個嵌套promise.then供應商?實際上,我想知道是否有一種方法可以在加載控制器之前存儲所有json數據?

(function(angular) { 
    'use strict'; 
    angular.module('myModule') 
    .controller('MainCtrl', ['$scope', 'config', function ($scope, config,){ 
     $scope.config = ?????????? ; 
     $scope.preferences = ???????????? ;    
    }]); 
})(window.angular); 
+0

如果您使用路由器這樣的[ngRoute](https://docs.angularjs.org/api/ngRoute)或[ui-router](https://ui-router.github.io/ng1/docs/latest/),您可以使用路由的resolve屬性來等待幾個API調用加載控件米勒。 – georgeawg

回答

3

只需撥打你的方法從服務config在你的控制器......

(function(angular) { 
    'use strict'; 
    angular.module('myModule') 
    .controller('MainCtrl', ['$scope', 'config', '$q', function ($scope, config, $q) { 
     config.getConfig().then(function(data) { 
     $scope.config = data; 
     }); 
     config.getPreferences().then(function(data) { 
     $scope.preferences = data; 
     }); 

     // or if you want, 
     // you can wait for the both requests to finish and get them at once 
     $q.all([ 
      config.getConfig(), 
      config.getPreferences() 
     ]) 
     .then(function(responses) { 
      $scope.config = responses[0]; 
      $scope.preferences = responses[1]; 
     }); 
    }]); 
})(window.angular); 

如果您在控制器的initializaation前想這個配置數據和您使用的路由器,就可以從路由器解析它,並且在控制器被觸發時它將可用。

路由器

$stateProvider 
    .state('stateName', { 
     url: '/stateURL', 
     templateUrl: 'path/to/the/template', 
     controller: 'MainCtrl', 
     resolve: { 
     configData: ['$q', config, function ($q, config) { 
      return $q.all([ 
      config.getConfig(), 
      config.getPreferences() 
      ]); 
     } 
    } 
    }); 

控制器

(function(angular) { 
    'use strict'; 
    angular.module('myModule') 
    .controller('MainCtrl', ['$scope', 'configData', function ($scope, configData) { 
     $scope.config = configData[0]; 
     $scope.preferences = configData[1]; 
    }]); 

編輯

+0

我已經做到了,但在這種情況下,$ scope.config和$ scope.preferences被封裝得如此有作用域。如果你在getConfig函數外執行console.log($ scope.config),那是錯誤的,因爲它是'未定義的'。 –

+0

不,它表明它是'undefined',因爲它在承諾解析之前被記錄。你可以在控制器中進行另一個測試,把這個'setTimeout(function(){console.log($ scope,$ scope.config);},50000); '告訴你看到了什麼? –

+0

因此,我更喜歡使用超時代碼的其他解決方案。我很確定還有另外一種方法可以確保數據在控制器之前加載並直接在其中使用。對於我來說setTimeout()有點髒。我想正確地做。 –

2

只需打電話給你getConfig功能和使用返回的承諾:

config.getConfig() 
    .then(function(data) { 
     // In your config factory you choose to return reponse.data so in this callback data = response.data 
     $scope.config = data 
    } 

config.getPreferences() 
    .then(function(data) { 
     // In your config factory you choose to return reponse.data so in this callback data = response.data 
     $scope.preferences = data 
    } 

在你的工廠,你換貨政...承諾並將其配置爲使用response.data進行解析,以便在解決返回的承諾時直接返回該字段。

+0

我已經做到了,但在這種情況下,$ scope.config和$ scope.preferences被封裝得如此作用域。如果你在getConfig函數外執行console.log($ scope.config),那是錯誤的,因爲它是'未定義的'。 –

+0

事實上,$ scope.config在解析promise之前是undefined,當promise被解析$ scope.config將是正確的。 –

1

我的問題是,當我必須得到兩個json數據,我應該承諾promise.then然後在promise.then。我想找到一個解決方案來加載所有的JSON數據之前執行的控制器

使用$q.all我的代碼要等好承諾完成:

var configPromise = config.getConfig(); 
var prefPromise = config.getPreferences(); 

$q.all([configPromise, prefPromise]).then(function(dataList) { 
    $scope.config = dataList[0]; 
    $scope.preferences = dataList[1]; 

    console.log($scope.config); 
    console.log($scope.preferences); 

    //Put more code here 
}); 

欲瞭解更多信息,請參閱AngularJS $q Service API Reference - $q.all


如果你在getConfig函數之外做console.log($scope.config),這是錯誤的,因爲它是undefined

這就是異步API的工作方式。在成功處理程序中的代碼在.then方法外部的所有代碼之後執行。

把控制檯。登錄處理函數:

config.getConfig().then(function successHandler(data) { 
    $scope.config = data 
    //HERE 
    console.log($scope.config); 
}; 

//NOT HERE 
̶c̶o̶n̶s̶o̶l̶e̶.̶l̶o̶g̶(̶$̶s̶c̶o̶p̶e̶.̶c̶o̶n̶f̶i̶g̶)̶;̶ 

承諾爲基礎的異步操作的釋

console.log("Part1"); 
console.log("Part2"); 
var promise = $http.get(url); 
promise.then(function successHandler(response){ 
    console.log("Part3"); 
}); 
console.log("Part4"); 

pic

控制檯日誌 「第四部分」 不必等待數據從服務器返回。它在XHR 開始後立即執行。 「Part3」的控制檯日誌位於$q service保存的成功處理程序函數中,並且在數據已從服務器到達並且XHR 完成後調用

欲瞭解更多信息,請參閱How to use $http promise response outside success handler.


演示

console.log("Part 1"); 
 
console.log("Part 2"); 
 
var promise = new Promise(r=>r()); 
 
promise.then(function() { 
 
    console.log("Part 3"); 
 
}); 
 
console.log("Part *4*");

+0

是的,我看到了。我的問題是,當我必須得到兩個json數據時,我應該承諾,然後在promise中。然後。我想找到一個解決方案來加載所有json數據,然後在控制器中執行我的代碼。 –

+0

我改變了我的問題更清晰;-) –

+0

使用[$ q.all](https://docs.angularjs.org/api/ng/service/$q#all)等待幾個承諾。查看更新以回答。 – georgeawg

相關問題