日々精進

新しく学んだことを書き留めていきます

AngularJSでスクロール領域内を更新したらスクロール位置が変わってしまう問題

解決が結構面倒だった。 まずng-repeatでスクロール領域内を更新していたので、更新完了イベントが必要だった。 以下のdirectiveを定義してng-repeat完了イベントを定義した。

module sample {
  'use strict';

  /**
   * ng-repeat処理完了イベントを発行するDirective
   */
  export class OnFinishRenderDirective implements ng.IDirective {
    public priority: number = -1;
    public restrict: string = 'A';
    public scope: any = {};
    private timeoutService: angular.ITimeoutService;
    public link: Function;

    /* @ngInject */
    constructor($timeout: angular.ITimeoutService) {
      this.timeoutService = $timeout;
      this.link = (scope: ng.IScope, element: ng.IAugmentedJQuery, attr: ng.IAttributes): any => {
        if ((<angular.IRepeatScope>scope.$parent).$last === true) {
          this.timeoutService(function() {
            scope.$emit('ngRepeatFinished');
          }, 0);
        }
      };
    }


    /* @ngInject */
    public static init($timeout : angular.ITimeoutService): any {
      return new OnFinishRenderDirective($timeout);
    }
  }
}

このon-finish-renderディレクティブはng-repeatを付けているタグに付ける。 後はスクロール領域のスクロールイベントで今表示中の位置を保存し、OnFinishRenderイベントでその値をスクロール位置に設定する。 あるあるな問題だろうからもっと楽な解決策ありそうだけどな。。

参考: