6

私は2つのものを含む角度スコープを持っています:

  • レンダリングに 1 秒かかる 10,000 行の巨大なテーブル
  • 固定オーバーレイ ヘッダー バーの上部にあるいくつかの小さな追加情報

ページ/テーブルをどれだけ下にスクロールしたかに応じて、ヘッダーの小さな情報ビットの 1 つを更新する必要があります。これは、スクロールした距離の % カウンターと考えることができます。

現在のスクロール位置を取得するために、ディレクティブを作成しました (ここでも見つけることができます)。

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

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

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

私の問題は、これによりテーブル内のスクロールが非常に遅くなることです*。これは、ディレクティブで書き込む veriable がスコープ内の追加情報にあり、それを変更すると、my$applyが呼び出されたときに angular がテーブル全体の変更をダーティチェックするように見えるためです。

このスクロールによってテーブル内の何も変更されないことはわかっており$apply、サイトのヘッダー部分に影響を与えるように制限したいと考えています。

angularテーブルをダーティチェックしないようにするにはどうすればよいですか?

4

2 に答える 2

3

Angular は、ダイジェストと呼ばれるプロセスの下でダーティ チェックを行います。を呼び出すと$scope.$digest()、 のすべての子スコープに伝播されます$scope。変更についてAngularに通知するには、通常、$scope.$apply(). $apply() angular の最後で、ルート スコープでダイジェストを実行します。これにより、アプリケーションのすべてのスコープでダイジェストがトリガーされます。したがって、大きなテーブル スコープを使用してスコープ内でのダイジェストを回避するには、追加情報スコープの子ではないことを確認する必要があります。ディレクティブで $scope.$apply() を実行するのではなく、 $scope.$digest(). これは少し紛らわしいかもしれないので、違いを示すプランカーを作成しました。コンソールを開いて、スクロール イベントとボタン クリックの違いを確認します。

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-world の関連するデータ/コントローラーの量を) 制限します。クライアントの配列にすべてのデータを保持することはできますが、常に小さなサブセットのみを Angular に公開します。

これを行う 1 つの方法は、 を使用してレンダリングする Angular-world にng-repeat小さな配列を作成し、スクロール位置に基づいて大きな非角度配列からこの小さな角度配列の要素を追加および削除することです。

このように、Angular はデータの小さなサブセットしか認識していないため、はるかに高速にレンダリングする必要があります。これは、DOM ツリーと 10k 行のレンダリングを維持する必要がないブラウザーの作業も大幅に削減されるため、一般的には非常にうまく機能すると思います。

于 2013-05-02T09:39:25.000 に答える