Angular - ngFor - 刷入数组的视图

时间:2017-10-31 14:01:29

标签: angular ngfor

我在处理文件时尝试向te用户显示一些详细日志。

我在*ngFor='let log of _loggerService.logs'中有一个div。然后我从input中选择一个文件,读取它(它是一个csv)并用

记录每一行
this._loggerService.verbose(`pushing row ${JSON.stringify(row)}`);

但是,div仅在处理完所有文件行后出现,而不是一次显示一行。

这是我的记录器服务:

@Injectable()
export class LoggerService {

    constructor(private changeDetectorRef: ChangeDetectorRef) { }

    private logs: ILog[] = [];

    private log(log: ILog) {
        this.logs.push(log);    
        this.logs = this.logs.slice();
        this.changeDetectorRef.markForCheck();
    }
}


UPDATE:

如果我等待每行处理5ms(并因此记录),它就可以工作 请注意,我实际上删除了ChangeDetectorRef字段,因为它不是必需的。

1 个答案:

答案 0 :(得分:1)

我已将此代码用于日志分页

这是分页的自定义标记

import {
  Component,
  Input, Output,
  ViewEncapsulation,
  EventEmitter,
  SimpleChanges,
  HostListener, ElementRef
} from '@angular/core';

@Component({
  selector: 'pagination',
  styles: [`
      .container {
        align-items: center;
        justify-content: flex-end;
      }
  `],
  template: `
      <div layout="row" class="container">
        <div >{{currentRow}}-{{ min( (currentRow + this.perPage - 1), total)}} of {{total | formattedNumber}}</div>
        <button [disabled]="this.currentRow==1" (click)="addToCurrent(-1)"><</button>
        <button [disabled]="this.total < (this.currentRow + this.perPage) " (click)="addToCurrent(1)">></button>
      </div>
    `
})


export class PaginationComponent {
  @Input('total')
  public total: number = 0;

  @Input('per-page')
  perPage: number = 20;

  @Input('current-row')
  currentRow: number = 1;


  @Input('scroll-area')
  scrollAreaElementRef: any;

  get currentPage(): number {
    return (this.currentRow - 1 / this.perPage) + 1;
  };

  @Output('page-change')
  pageChange: EventEmitter<PageParams> = new EventEmitter<PageParams>();

  pageSeries: number[] = new Array<number>();


  @HostListener('window:mousewheel', ['$event']) onMouseWheelChrome(event: any) {
    this.mouseWheelFunc(event);
  }

  @HostListener('window:DOMMouseScroll', ['$event']) onMouseWheelFirefox(event: any) {
    this.mouseWheelFunc(event);
  }

  @HostListener('window:onmousewheel', ['$event']) onMouseWheelIE(event: any) {
    this.mouseWheelFunc(event);
  }



  mouseWheelFunc(event) {
    //Guess the delta.
    let delta = 0;
    if (event.wheelDelta) {
      delta = -1 * event.wheelDelta / 120;
    } else if (event.detail) {
      delta = event.detail / 3;
    }

    if (this.scrollAreaElementRef != null && event.target != null) {
      if (!this.isDescendant(this.scrollAreaElementRef, event.target)) {
        return false;
      } else {
        if (event.preventDefault)
          event.preventDefault();
      }
    }

    let newRow = (this.currentRow + ((delta > 0 ? Math.ceil(delta) : Math.floor(delta)) * this.perPage));
    this.gotoRow(newRow);
  }

  isDescendant(parent, child): boolean {
    let node = child.parentNode;
    while (node != null) {
      if (node == parent) {
        return true;
      }
      node = node.parentNode;
    }
    return false;
  }


  min(v: number, v2: number) {
    if (v < v2)
      return v;
    else
      return v2;
  }


  gotoRow(row: number) {
    // set min
    if (row < 1)
      row = 1;

    // set max
    if (row > (this.total - this.perPage + 1))
      row = (this.total - this.perPage + 1);

    this.pageChange.emit(new PageParams(row, this.perPage));
  }

  addToCurrent(val: number) {
    this.gotoRow(this.currentRow + (val * this.perPage));
  }

  constructor() {

  }
}

export class PageParams {
  constructor(
    public start: number,
    public pageSize: number) {

  }
}

并将该代码放入您的网页

<div class="" layout="column" style="align-items: stretch; width: 50%">
    <div #dataCard>
        <div layout="row" style="align-items: center;justify-content: start;">
            <div class="md-title"> Job Logs </div>
            <pagination style="width:auto;margin-left: auto" [total]="totalRows" [per-page]="rowsPerPage" [current-row]="rowStart" [scroll-area]="dataCard"
                (page-change)="pageChange($event)"></pagination>
        </div>
        <pre style="margin-top: 0px;">
            <div *ngFor="let i of displayIndexArray" class="app-content" layout="row" style="align-items: stretch;">
                <ng-template [ngIf]="displayArray[i]?.log === null || displayArray[i]?.log === ''"><br/></ng-template>
                <ng-template [ngIf]="displayArray[i]?.log != null && displayArray[i]?.log != ''"><span>{{ displayArray[i]?.log }}</span></ng-template>
            </div>
        </pre>
    </div>
</div>

此代码在页面ts文件

private _rowsPerPage: number = 34;
private _totalRows: number = 0;
private _rowStart: number = 1;
private displayArray: Log[] = new Array(this._rowsPerPage).fill(undefined);
private displayIndexArray: number[] = new Array(this._rowsPerPage).fill(0).map((x, i) => i);

get rowsPerPage(): number {
    return this._rowsPerPage;
}

get rowStart(): number {
    return this._rowStart;
}

get totalRows(): number {
    return this._totalRows;
}

private pageChange(pageParams: PageParams) {
    this._rowStart = pageParams.start;
    this._rowsPerPage = pageParams.pageSize;

    this.loadLog();
}

private loadLog() {
    let logs: Log[] = new Array();

    this._totalRows = logs.length;

    // so that pagination does not damaged when totalRows are less than rowsPerPage
    if (logs.length < 34) {
        this._rowsPerPage = logs.length;
    } else {
        this._rowsPerPage = 34;
    }

    this.displayArray.forEach((row, index, array) => {
        array[index] = logs[index + this._rowStart - 1];
    });
}