pet*_*pod 14 scope asynchronous angularjs
在向API发出请求时,我无法在前端更新我的示波器.在后端我可以看到我的$ scope变量的值正在改变,但这并没有在视图中反映出来.
这是我的控制器.
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);
      });
    });  
 }
});
这是我的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>
我尝试了几种解决方案,包括使用$ scope.$ apply(); 但这只会产生常见错误
错误:$ digest已在进行中
以下帖子建议使用$ timeout或$ asyncDefault AngularJS:在调用$ scope时防止错误$ digest正在进行中.$ apply()
我上面的代码使用$ timeout,我没有错误,但视图仍未更新.
帮助赞赏
Vla*_*nek 12
我使用的是AngularJS 1.3+,您可以$scope.$applyAsync()在$scope.beers = response.data;声明后立即尝试.
这是Angular文档所说的内容 $applyAsync()
安排$ apply的调用在以后发生.实际时间差异因浏览器而异,但通常约为10毫秒.资源
更新
正如其他人所指出的,你不应该(通常)需要手动触发摘要周期.大多数时候,它只是指向您的应用程序的糟糕设计(或至少不是AngularJS友好设计).
目前在OP中,该fetch方法是在$ watch上触发的.如果要触发该方法ngChange,则应自动触发摘要周期.
以下是此类代码的示例:
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);
    };
}
正如评论所建议的,您不需要使用$timeout来触发摘要周期。只要引起变化的用户体验在角度构造的范围内(例如控制器功能、服务等),那么它就应该在摘要周期内体现出来。
根据我从您的帖子中推断出的信息,您可能正在使用搜索输入来访问 API 并获取结果。我建议更改逻辑,以便您在显式事件而不是$watch呃事件上触发搜索。
<input ng-model="search" ng-change="fetch()">
删除$watch逻辑和$timeout包装器。
function fetch(){
    var query = "http://api.com/v2/search?q=" + $scope.search + "&key=[API KEY]&format=json";
$http.get(query)
.then(function(response){ 
    $scope.beers = response.data; 
    console.log($scope.beers);
    //it's a good habit to return your data in the promise APIs
    return $scope.beers;  
});
}
我提出这个建议的原因是:
ng-change回调的触发方式ng-model-options。这意味着您可以延迟它,可以触发各种 UX 事件等。fetch。| 归档时间: | 
 | 
| 查看次数: | 11743 次 | 
| 最近记录: |