6

我有一个包含两件事的角度范围:

  • 一张有 10k 行的巨型表,需要一秒钟才能呈现
  • 固定覆盖标题栏中的一些小的额外信息

根据您向下滚动页面/表格的距离,我必须更新标题中的一个小信息位;您可以将其视为您滚动了多远的百分比计数器。

为了获得当前的滚动位置,我写了一个指令(你也可以在这里找到它):

app.directive "setWindowScroll", ->
  restrict: "E"
  scope:
    setVariable: "="

  link: (scope) ->
    $(window).scroll ->

      scope.$apply ->
        scope.setVariable = $(window).scrollTop()

我的问题是,这使得在表格中滚动你*可能会很慢*。这是因为我用我的指令写的验证是在范围内的额外信息中,并且改变它似乎会导致 angular 在$apply调用 my 时检查整个表是否有变化。

我知道这种滚动永远不会改变我的表格中的任何内容,并且希望限制我$apply影响我网站的标题部分。

我怎样才能让角度脏检查桌子?

4

2 回答 2

3

Angular 在一个称为摘要的过程下进行脏检查。当您调用$scope.$digest()它时,它将传播到$scope. 要通知 Angular 有关更改,您通常会执行$scope.$apply(). 在 $apply() 角度的末尾,对根范围进行摘要,这会触发对应用程序中每个范围的摘要。因此,为了避免使用大表范围在您的范围内进行摘要,您应该确保它不是额外信息范围的子级,而不是在您的指令中执行 $scope.$apply() 您可以执行$scope.$digest()。这可能有点令人困惑,所以我制作了一个试图显示差异的 plunker。打开你的控制台,看看滚动事件和按钮点击的区别:

http://plnkr.co/edit/45gKhAIt0DrozS7f0Bz2?p=preview

// this will only cause a digest in the current scope and its children
angular.element($window).bind('scroll',function(){
  $scope.scrollY = $window.scrollY;
  $scope.$digest();
})

// this will cause a digest in every scope
angular.element($window).bind('scroll',function(){
  $scope.scrollY = $window.scrollY;
  $scope.$apply();
})

说了这么多,这是一件非常不寻常的事情 - 由于多种原因可能不是一个好主意(角度不能很好地适应数千个元素,你不能使用任何角度事件指令(ngClick等)因为它们都包含在 $apply 中) - 但是如果您无法在服务器端呈现表格,您可以尝试一下。

于 2013-05-02T12:43:38.373 回答
0

我想知道这是否也可以这样做,但是——无论如何——你可能想考虑不要一次绘制整个表格。

而是将其(以及 Angular 世界中相关数据/控制器的数量)限制为仅基于当前滚动位置可见的行 + 上方和下方的一些缓存行。您仍然可以将所有数据保存在客户端的数组中,但随时只向 Angular 公开一小部分数据。

一种方法可能是在 Angular-world 中使用一个小数组进行渲染ng-repeat,然后根据滚动位置从大的非角度数组中添加和删除这个小角度数组中的元素。

这样,Angular 只知道一小部分数据,并且渲染速度应该更快。我认为这通常应该工作得很好,因为对于不需要维护 DOM 树和渲染 10k 行的浏览器来说,它的工作也少得多。

于 2013-05-02T09:39:25.000 回答