AngularJS Scope 在异步调用后未在视图中更新 [英] AngularJS Scope not updating in view after async call
问题描述
我在向 API 发出请求时在前端更新我的范围时遇到问题.在后端,我可以看到 $scope 变量的值正在发生变化,但这并没有反映在视图中.
这是我的控制器.
Controllers.controller('searchCtrl',函数($scope,$http,$timeout){$scope.$watch('搜索', function() {拿来();});$scope.search = "福尔摩斯";函数获取(){var query = "http://api.com/v2/search?q=" + $scope.search + "&key=[API KEY]&format=json";$超时(功能(){$http.get(查询).then(功能(响应){$scope.beers = response.data;控制台日志($scope.beers);});});}});
这是我的 html 片段
正在加载结果...<p>啤酒:{{啤酒}}</p><div ng-if="beers.status==='success'">
<div class='col-xs-8 .col-lg-8' ng-repeat="beer in beer.data track by $index" ng-if="beer.style"><h2>{{beer.name}}</h2><p>{{beer.style.description}}</p><小时>
<div ng-if="beers.status==='失败'"><p>未找到任何结果.</p>
我尝试了多种解决方案,包括使用 $scope.$apply(); 但这只会造成常见错误
<块引用>错误:$digest 已在进行中
以下帖子建议使用 $timeout 或 $asyncDefaultAngularJS:防止错误 $digest 已经在进行中调用 $scope.$apply()
我上面的代码使用 $timeout 并且我没有错误,但视图仍然没有更新.
感谢帮助
我您使用的是 AngularJS 1.3+,您可以在 $scope 之后立即尝试
声明.$scope.$applyAsync()
.beers = response.data;
这是 Angular 文档中关于 $applyAsync()
安排 $apply 的调用在以后发生.实际时间差异因浏览器而异,但通常约为 10 毫秒.来源
更新
正如其他人指出的那样,您(通常)不需要手动触发摘要循环.大多数情况下,它只是指向应用程序的糟糕设计(或者至少不是 AngularJS 友好设计).
目前在 OP 中,fetch
方法是在 $watch 上触发的.如果该方法由 ngChange
触发,则摘要循环应自动触发.
以下是此类代码的示例:
HTML
//请注意controller as"语法是首选,但这超出了本问题/答案的范围<input ng-model="search" ng-change="fetchBeers()">
JavaScript
function SearchController($scope, $http) {$scope.search = "福尔摩斯";$scope.fetchBeers = 函数 () {const 查询 = `http://api.com/v2/search?q=${$scope.search}&key=[API KEY]&format=json`;$http.get(query).then(response => $scope.beers = response.data);};}
I am having trouble updating my scope on the front-end while making a request to an API. On the backend I can see that the value of my $scope variable is changing but this is not being reflected in the views.
Here is my controller.
Controllers.controller('searchCtrl',
function($scope, $http, $timeout) {
$scope.$watch('search', function() {
fetch();
});
$scope.search = "Sherlock Holmes";
function fetch(){
var query = "http://api.com/v2/search?q=" + $scope.search + "&key=[API KEY]&format=json";
$timeout(function(){
$http.get(query)
.then(function(response){
$scope.beers = response.data;
console.log($scope.beers);
});
});
}
});
Here is a snippet of my html
<div ng-if="!beers">
Loading results...
</div>
<p>Beers: {{beers}}</p>
<div ng-if="beers.status==='success'">
<div class='row'>
<div class='col-xs-8 .col-lg-8' ng-repeat="beer in beers.data track by $index" ng-if="beer.style">
<h2>{{beer.name}}</h2>
<p>{{beer.style.description}}</p>
<hr>
</div>
</div>
</div>
<div ng-if="beers.status==='failure'">
<p>No results found.</p>
</div>
I've tried several solutions including using $scope.$apply(); but this just creates the common error
Error: $digest already in progress
The following post suggested to use $timeout or $asyncDefault AngularJS : Prevent error $digest already in progress when calling $scope.$apply()
The code I have above uses $timeout and I have no errors but still the view is not updating.
Help appreciated
I you are using AngularJS 1.3+, you can try $scope.$applyAsync()
right after $scope.beers = response.data;
statement.
This is what Angular documentation says about $applyAsync()
Schedule the invocation of $apply to occur at a later time. The actual time difference varies across browsers, but is typically around ~10 milliseconds. Source
Update
As others have pointed out, you should not (usually) need to trigger the digest cycle manually. Most of the times it just points to a bad design (or at least not an AngularJS-friendly design) of your application.
Currently in the OP the fetch
method is triggered on $watch. If instead that method was to be triggered by ngChange
, the digest cycle should be triggered automatically.
Here is an example what such a code might look like:
HTML
// please note the "controller as" syntax would be preferred, but that is out of the scope of this question/answer
<input ng-model="search" ng-change="fetchBeers()">
JavaScript
function SearchController($scope, $http) {
$scope.search = "Sherlock Holmes";
$scope.fetchBeers = function () {
const query = `http://api.com/v2/search?q=${$scope.search}&key=[API KEY]&format=json`;
$http.get(query).then(response => $scope.beers = response.data);
};
}
这篇关于AngularJS Scope 在异步调用后未在视图中更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!