Angularjs 将$http响应对象另存为$scope变量
今天早些时候我问了一个关于stackoverflow的相关问题,但由于代码的复杂性(无法发布),以及我自己的新手身份,我无法根据给出的答案真正实现解决方案 所以我现在的问题是,对于这样的代码:Angularjs 将$http响应对象另存为$scope变量,angularjs,http,Angularjs,Http,今天早些时候我问了一个关于stackoverflow的相关问题,但由于代码的复杂性(无法发布),以及我自己的新手身份,我无法根据给出的答案真正实现解决方案 所以我现在的问题是,对于这样的代码: $http.get(ArbitraryInput).then(function (response) {$scope.data = response}); <pre>{{ctrl.data|json:4}}</pre> (您可以用上面的“success”替换“then”,我使用
$http.get(ArbitraryInput).then(function (response) {$scope.data = response});
<pre>{{ctrl.data|json:4}}</pre>
(您可以用上面的“success”替换“then”,我使用“then”,因为根据更新的$http api,success是不推荐使用的)
如何将响应对象保存在$scope.data中?从我到目前为止所做的工作来看,$scope.data
在我稍后键入代码时是“未定义的”:
console.log($scope.data3);
谢谢
更新一个
显然,如果我把console.log($scope.data)
内部控制台将显示我想要的$scope.data
。但如果它在外部,它将在控制台中保持“未定义”。换言之:
$http.get(ArbitraryInput).then(function (response) {$scope.data = response; console.log($scope.data);});
将返回任何类型的对象响应。在控制台中,但是
$http.get(ArbitraryInput).then(function (response) {$scope.data = response;});
console.log($scope.data);
将在控制台中返回“未定义”。尝试以下操作:
$http.get(ArbitraryInput).then(function (response) {
$scope.data = response;
console.log($scope.data);
});
$http.get是。
请注意,这是一个承诺(异步请求),因此如果您这样做
$http.get(ArbitraryInput).then(function (response) {$scope.data = response;});
console.log($scope.data)
$http.get(ArbitraryInput).then(function (response) {
$scope.data = response;
console.log($scope.data);
});
当您尝试在请求完成之前记录它时,它可能不会记录任何内容
所以你可能需要用这样的东西
$http.get(ArbitraryInput).then(function (response) {$scope.data = response;});
console.log($scope.data)
$http.get(ArbitraryInput).then(function (response) {
$scope.data = response;
console.log($scope.data);
});
因此,您确信console.log将在分配给$scope.data后执行。您需要利用$http.get返回承诺的事实,并在需要访问解析数据的任何代码中链接到该承诺:
app.controller('Ctrl', function($scope, mainInfo){
var request = $http.get(ArbitraryInput).then(function (response) {
$scope.data = response;
return response; // this will be `data` in the next chained .then() functions
});
request.then(function (data) {/* access data or $scope.data in here */});
$scope.someFunction = function () {
request.then(function (data) {/* access data or $scope.data in here */);
};
}) ;
问题已得到回答,但我想提供一个替代解决方案,以防立即需要数据。与直接在控制器/指令中调用$http服务不同,您可以将该数据解析为路由中的依赖项,以便数据立即可用:
angular.module('myApp')
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/home', {
templateUrl: '/path/to/template',
controller: 'myCtrl',
controllerAs: 'ctrl',
resolve: {
myData: ['$http', function($http) {
return $http.get('/end/point');
}
}
}
}]);
然后,您的控制器可以如下所示:
angular.module('myApp')
.controller('myCtrl', ['myData', function(myData) {
var self = this;
self.data = myData;
}]);
在你看来:
{{ctrl.data | json:4}
将所有数据显示为JSON,而无需在控制器中调用$http。这是一个实用的答案,由用户提供。答案底部的实际使用示例
如果像我一样,您需要将该响应对象用作范围变量,那么这里有一个技巧:
这将在控制台中返回“undefined”,与我一样,您可能无法在页面上使用该响应数据:
$http.get(ArbitraryInput)
.then(function (response) {
$scope.data = response;
$scope.$apply()
});
然而,这应该是可行的:
$http.get('api/recipe/' + currentRecipeId).then(
function (data) {
$scope.recipe = data.data;
$scope.form = $scope.recipe;
$scope.$apply()
}
);
$scope.$apply()
将持久化响应对象,以便您可以使用该数据
-
为什么需要这样做?
我一直在尝试为我的食谱应用程序创建一个“编辑”页面。
我需要用所选配方的数据填充我的表单。
在发出GET请求并将响应数据传递到$scope.form之后,我什么也没有得到<代码>$scope.$apply(),并在很大程度上发挥了作用。干杯,伙计
以下是我的editRecipeController中的示例:
希望有帮助 $http.get($scope.coveragesDEMO).then(函数(响应){$scope.data=response.data});你能看看吗?谢谢你的回复。我试过了,但没用。未定义console.log(response.data),但仍然定义console.log(response)。console.log($scope.data)在所有场景中仍然未定义扫描您发布得到的响应?在then之外执行的
console.log
在then回调中的赋值之前执行,这就是为什么它输出未定义响应可能会记录为undefined
,因为它在收到get响应之前不会被设置。但是,它将在您获得数据时设置,因此可在控制器和视图中使用。感谢您的回复。我试过了,它确实在控制台中提供了我想要的东西,但是我仍然在试图弄清楚如何将控制器$scope变量永久设置为对象的响应。函数外部对变量的任何引用似乎都返回“未定义”。LargeCrimsonFish,函数外部的引用需要等到解析$http.get后才能访问$scope变量。@LargeCrimsonFish,通过运行$scope.$watch方法并注销数据,可以观察$scope对象的实际情况。所以$scope.$watch('data',函数(newValue,oldValue){console.log(newValue,oldValue);});您将看到,$scope.data值仅在$http调用被解析后才被更新,但将尽快绑定到视图。如果要对该数据执行某些操作,则必须在解析之后执行(在其他函数/服务中)。如果您立即需要该数据,请查看路由中的“解析”属性。是的,您是对的。我没有意识到这是一个异步操作,因为我对它还很陌生。在这种情况下,是否可以执行类似$http.get().then(dothisfirst)和(dothisafter)的操作我不明白,您想做什么??在什么?LargeCrimsonFish之前和之后,请参阅我的答案,在分辨率上设置范围变量,然后从控制器中的其他函数访问它。谢谢你节省了我的时间:)。这当然是解决这个问题的最简单的方法。很高兴它起了作用