【问题标题】:ng-repeat list doesn't update immediately after api callng-repeat 列表在 api 调用后不会立即更新
【发布时间】:2015-06-12 20:09:17
【问题描述】:

我的网络应用程序视图在嵌套列表中列出文件夹及其子项:

<ul>
  <li class="folderLi" ng-repeat="folder in folders">
    <a href="" ng-click="listFolderFiles( folder )">{{folder.title}}</a>
    <ul >
      <li ng-repeat="child in folder.children">
          {{child.title}}
      </li>
    </ul>
  </li>
</ul>

当我加载文件夹的初始列表时,列表会立即更新以显示文件夹。但是,此时每个文件夹上都没有子对象。当单击文件夹并且应用程序调用 Google Drive API 来检索文件夹的子项时,就会填写该信息。控制器包含这个功能:

$scope.listFolderFiles = function( folder ) {
  var request = gapi.client.request({
    'path': '/drive/v2/files',
    'method': 'GET',
    'params' : {
        'q' : "'" + folder.id + "' in parents"
      }
  });


request.then(function(response){
     //log successful response
     console.log(response);
     folder.children = response.result.items;
           }, function(response) {
     //log error
      console.log(response);
   })
  }

此函数正确检索信息并更新模型。但是,子项的 ng-repeat 列表不会立即更新和显示。相反,它会在下次单击文件夹时更新并显示。似乎这个函数在 api 调用完成之前更新了视图,所以下次函数运行时,视图会更新以显示最后一次 API 调用的响应。想法?

【问题讨论】:

  • 尝试使用$scope.$apply();强制摘要循环
  • 你不能将文件夹添加为 $scope var 吗?它可以强制 angular 跟踪它。
  • 看看github.com/pinoyyid/ngGAPI 这是一个基于 Angular 的库,以 AngularJS 的方式执行 Google Drive。目前是早期的 alpha,但可能足够稳定供您使用。您问题中的所有代码都将替换为单行 folder.children = DriveService.files.list({q:"'" + folder.id + "' in parents"},true).data 。免责声明:我是作者。
  • 顺便说一句,请注意,您粘贴的代码也会返回已删除的文件。这可能是故意的,但更常见的是在 q 属性中看到“trashed=false”。
  • 感谢您在我问这个问题之前回答我关于如何停止获取已删除文件的问题。

标签: javascript angularjs google-drive-api angularjs-ng-repeat


【解决方案1】:

您正在尝试更新 Angular 之外的知识。所以你的观点没有更新。您需要使用$scope.$apply()$timeout 来运行摘要循环。

request.then(function(response){
     //log successful response
     console.log(response);
     //folder.children = response.result.items; //Required in case of $scope.$apply()
     $timeout(function(){folder.children = response.result.items;}); //Or $scope.$apply(); (Don't forget to inject $timeout in your controller)
           }, function(response) {
     //log error
      console.log(response);
   })
  }

【讨论】:

  • 你是正确的 Zee,但是,在我看来,直接使用 $apply 并不是一个好习惯。我宁愿建议将内容包装到 $timeout(function(){},0);
  • @aorfevre。是的,你是对的,我忘记了。 :) 我也更喜欢$timeout。不知道我是怎么错过的。更新。 :)
  • 即使$timeout 也不是好的做法。使用$q 包装外部承诺。 $q 将在内部触发摘要循环。
  • @Yoshi。只是出于好奇,为什么不$timeout
  • @Zee 因为感觉很脏 ;) 不是真的,我只是认为 $timeout 并不是真的要用于此目的,它只是一个实现细节,它将对应用程序。
猜你喜欢
  • 2016-12-15
  • 1970-01-01
  • 2022-09-28
  • 1970-01-01
  • 2015-03-02
  • 2016-04-20
  • 2015-09-15
  • 2015-08-08
  • 1970-01-01
相关资源
最近更新 更多