Controller 之后的服务 运行? returns 未定义
Service run after Controller? returns undefined
我正在将 json 数据加载到我的应用程序中,但它总是 return 未定义。
经过多次测试和更改后,我发现该服务在控制器之后运行,或者至少我认为是这样。
服务
.factory('personService', function($http) {
return {
getPersons: function() {
return $http.get('/persons.php');
}
}
})
控制器
.controller('personsCtrl', function($scope, personService) {
var promise = personService.getPersons();
promise.then(
function(response) {
$scope.persons = response.data;
console.log(response.data);//first
},
function(response) {
console.log('failed loading');
});
console.log($scope.persons); //last
})
控制台在 //first 之前打印出 //last,这意味着它可能在从 json 文件获取数据之前运行。
控制台
undefined
[object object object]
有人知道我在这里做错了什么吗?谢谢。
这就是它的工作方式。你为什么担心 "console.log($scope.persons); //last" 你需要在控制器中获取数据,你正在获取它。在 $http 调用之后,您的 $scope.person 正在更新,这将依次更新您的视图。
您如何确定 "console.log($scope.persons);" 比“ console.log(response.data);”先执行?
尝试如下修改您的服务。
.factory('personService', function($http) {
var getPersons= function() {
return $http.get('/persons.php').then(function(result){
return result.data;
});
};
return { getPersons: getPersons};
});
您的代码非常好,无需更改。
我不会听从 Vamsi 的建议 - 对不起,伙计 - 因为在控制器中解决承诺总是比立即解决它更好。
这样做的原因是在某些时候您可能希望将它 (getPersons
) 与来自其他服务的其他承诺链接起来:
personService.getPersons()
.then(function(result){
return service2.doSomething(result);
})
.then(function(result){
return service3.doSomeOtherThing(result);
})
.then(function(result){
return service4.doLastThing(result);
})
.catch(function (reason) {
console.log(reason);
})
.finally(function(){
// always executed.
});
如果您查看这段代码,您会看到一个典型的承诺链,其中每个服务都使用前一个承诺的结果,然后 returns 它到链的下一个分支。
如果发生错误,您可以catch
错误并继续。
回到你的问题:
.controller('personsCtrl', function($scope, personService) {
var promise = personService.getPersons();
promise.then(
function(response) {
$scope.persons = response.data;
console.log(response.data);//first
},
function(response) {
console.log('failed loading');
});
console.log($scope.persons); //last
});
承诺可能会延迟,尤其是在处理 $http
请求时。
console.log($scope.persons); //last
将立即被调用,因为代码是从上到下执行的,并且承诺 - 再次 - 可能会有一些延迟。
在实际情况下,您将在控制器中定义一个空数组:
.controller('personsCtrl', function($scope, personService) {
$scope.persons = [];
});
调用服务并等待服务returns数据:
.controller('personsCtrl', function($scope, personService) {
$scope.persons = [];
personService.getPersons()
.then(function(result){
$scope.persons = result.data;
});
});
并填充将绑定到 UI 的 $scope.persons
并更新界面。
如果您在填充 $scope.persons
之前需要做一些其他事情,您可以使用另一个 promise 链接。
如果您想更深入地了解 promises,我建议您阅读这篇文章 article,这是我找到的最好的解释。
如果您有兴趣遵循一些关于控制器、承诺和构建服务方式的非常好的指南John Papa Style Guide。
我正在将 json 数据加载到我的应用程序中,但它总是 return 未定义。 经过多次测试和更改后,我发现该服务在控制器之后运行,或者至少我认为是这样。
服务
.factory('personService', function($http) {
return {
getPersons: function() {
return $http.get('/persons.php');
}
}
})
控制器
.controller('personsCtrl', function($scope, personService) {
var promise = personService.getPersons();
promise.then(
function(response) {
$scope.persons = response.data;
console.log(response.data);//first
},
function(response) {
console.log('failed loading');
});
console.log($scope.persons); //last
})
控制台在 //first 之前打印出 //last,这意味着它可能在从 json 文件获取数据之前运行。
控制台
undefined
[object object object]
有人知道我在这里做错了什么吗?谢谢。
这就是它的工作方式。你为什么担心 "console.log($scope.persons); //last" 你需要在控制器中获取数据,你正在获取它。在 $http 调用之后,您的 $scope.person 正在更新,这将依次更新您的视图。
您如何确定 "console.log($scope.persons);" 比“ console.log(response.data);”先执行?
尝试如下修改您的服务。
.factory('personService', function($http) {
var getPersons= function() {
return $http.get('/persons.php').then(function(result){
return result.data;
});
};
return { getPersons: getPersons};
});
您的代码非常好,无需更改。
我不会听从 Vamsi 的建议 - 对不起,伙计 - 因为在控制器中解决承诺总是比立即解决它更好。
这样做的原因是在某些时候您可能希望将它 (getPersons
) 与来自其他服务的其他承诺链接起来:
personService.getPersons()
.then(function(result){
return service2.doSomething(result);
})
.then(function(result){
return service3.doSomeOtherThing(result);
})
.then(function(result){
return service4.doLastThing(result);
})
.catch(function (reason) {
console.log(reason);
})
.finally(function(){
// always executed.
});
如果您查看这段代码,您会看到一个典型的承诺链,其中每个服务都使用前一个承诺的结果,然后 returns 它到链的下一个分支。
如果发生错误,您可以catch
错误并继续。
回到你的问题:
.controller('personsCtrl', function($scope, personService) {
var promise = personService.getPersons();
promise.then(
function(response) {
$scope.persons = response.data;
console.log(response.data);//first
},
function(response) {
console.log('failed loading');
});
console.log($scope.persons); //last
});
承诺可能会延迟,尤其是在处理 $http
请求时。
console.log($scope.persons); //last
将立即被调用,因为代码是从上到下执行的,并且承诺 - 再次 - 可能会有一些延迟。
在实际情况下,您将在控制器中定义一个空数组:
.controller('personsCtrl', function($scope, personService) {
$scope.persons = [];
});
调用服务并等待服务returns数据:
.controller('personsCtrl', function($scope, personService) {
$scope.persons = [];
personService.getPersons()
.then(function(result){
$scope.persons = result.data;
});
});
并填充将绑定到 UI 的 $scope.persons
并更新界面。
如果您在填充 $scope.persons
之前需要做一些其他事情,您可以使用另一个 promise 链接。
如果您想更深入地了解 promises,我建议您阅读这篇文章 article,这是我找到的最好的解释。
如果您有兴趣遵循一些关于控制器、承诺和构建服务方式的非常好的指南John Papa Style Guide。