尝试在部件

时间:2017-07-21 12:42:43

标签: javascript angularjs

我目前在视图中显示数组的内容,比如说$scope.array

我使用请求加载数组的内容到我的serv。 遗憾的是$scope.array包含很多元素,在视图中一次显示每个元素需要一段时间。

为了增强用户体验,我想逐个部分地显示数组。起初我认为$scope能够处理它,如果我继续按块添加数据块到$scope.array,但是没有。

我发现当我的数组已满时,当前的$digest循环才会结束。我尝试使用Async lib向$scope异步添加块,希望找到一种方法来避开$digest问题,但它不起作用。

现在我有点想法正确显示数据,所以如果您对此类问题有任何经验,我很高兴听到它!

非常感谢。

2 个答案:

答案 0 :(得分:0)

使用服务器端分页。即使使用一次性绑定也不总是解决方案,特别是如果存在复杂的模板逻辑(根据数据属性显示/隐藏部分)以及是否需要编辑。

如果要按某些条件(例如月份和年份)过滤数组,请在后端实现此操作并将条件传递给服务器:GET /my_data?year=2017&month=7&page=1

答案 1 :(得分:0)

如果分页,定期请求等被排除,那么......

您可以将所有数据放在一个未绑定到ui的数组中。 然后,您定期将数据添加到绑定到ui的第二个数组中。与您提到的方式类似,您已经在执行此操作,但只需在$ timeout或$ interval中添加块。这样就可以完成$摘要和页面渲染。

简单示例:

<table>
  <tr ng-repeat="item in shownItems track by $index">
    <td>{{item}}</td>
  </tr>
</table>

并在控制器中

app.controller('MainCtrl', ['$scope', '$timeout', function($scope, $timeout) {
  //array that is bound to ui
  $scope.shownItems = [];
  //backing data 
  var fullItemsList = [];
  //Create some fake data, you wouldn't do this in your program,
  // this is where you would fetch from server
  for(var ii = 0; ii < 50000; ii++){
    fullItemsList.push("AYYYLMAO "  + ii);
  }

  //How many items to add at a time
  var chunkSize = 500;
  //keep track of how many we have already added
  var currentChunkIndex = 0;

  //transfers a chunk of items to ui-bound array 
  function addMoreItems(){
    var start = currentChunkIndex * chunkSize;
    var end = (currentChunkIndex + 1) * chunkSize;
    for(var ii = start; ii < end; ii++){
      if(!fullItemsList[ii]){
        break;
      }
      $scope.shownItems.push(fullItemsList[ii]);
    }
    currentChunkIndex++;
  }

  //Transfer chunk of items in a timeout, trigger another timeout to 
  //add more if there are stil items to transfer
  function periodicAdd(){
    $timeout(function(){
      addMoreItems();
      if(currentChunkIndex*chunkSize >= $scope.shownItems.length){
        periodicAdd();
      }
    },0);
  }
  //Add the first chunk straight away, otherwise it will wait for the 
  //first timeout.
  addMoreItems();
  //Start the timeout periodic add.
  periodicAdd();
}]);

Example plunkr

请记住,此示例非常粗糙。例如,50k行的初始“加载”将在ui线程上运行,而您的数据加载可能会从您的服务器异步。这也意味着只有在您的请求完成时才需要启动定期添加。所以,这只是一个粗略的例子。

请注意,我使用了0毫秒的超时。这仍然会将回调推送到当前处理队列的末尾,尽管是0毫秒,它仍然不会立即执行。您可能希望稍微增加一点,为您的应用程序提供一些喘息的空间。记住妥善处理超时。