У меня есть контроллер (MyCtrl). Первое, что нужно сделать, это сделать вызов http.get
и получить ответ и назначить его $scope.input
. Остальная часть контроллера зависит от $scope.input
. Но проблема в том, что код в контроллере пытается получить доступ к $scope.input
до завершения HTTP-вызова.
Как я могу это решить?
app.controller('MyCtrl', function($scope, $http, $routeParams, factory) {
factory.getInfo($routeParams.id)
.success(function(response) {
//The factory code make the http.get call
$scope.input = response;
});
//Rest of code accessing $scope.input before it is ready
});
PS: Я не хочу размещать rest of controller code
внутри блока success
благодаря
Вариант-1: использование некоторой функции intialize
Вы можете переместить логику инициализации на функцию, называемую initialize()
а затем вызвать функцию в обратном вызове успеха вашего вызова AJAX.
app.controller('MyCtrl', function($scope, $http, $routeParams, factory) {
factory.getInfo($routeParams.id)
.success(function(response) {
initialize(response);
});
function initialize(){
/* Move only the logic that depends on response from AJAX call in to
this method.
All utility functions, event handlers on scope are still outside
this function
*/
$scope.input = response;
}
});
Вариант-2: использование решения
Вы также можете использовать функцию resolve
для загрузки всех зависимостей перед инициализацией контроллера, как показано ниже.
В вашем маршрутизаторе-config
$routeProvider
.when('/home/:id', {
templateUrl: 'home.html',
controller: 'MyCtrl',
resolve: {
factory : 'factory',
initData: function(factory,$route){
return factory.getInfo($route.current.params.id);
}
}
});
В вашем контроллере
app.controller('MyCtrl', function($scope, $http, initData){
$scope.input = initData;
// rest of your logic
});
Для получения дополнительной информации об этом шаблоне-активизации и маршрутизации-контроллера вы можете обратиться к этому и этому.
Надеюсь это поможет :)