Как проверить, отображается ли элемент в угловых 2 - PullRequest
0 голосов
/ 30 апреля 2018

Я хочу показать всплывающее окно после полной загрузки таблицы. Я использую свойство load, но оно не работает. Есть ли другой способ добиться этого? Без концепции родитель-ребенок.

следующий мой код component.ts

export class FileUploadComponent {
    public files: UploadFile[] = [];
    data: AOA = [ [1, 2], [3, 4] ];
    wopts: XLSX.WritingOptions = { bookType: 'xlsx', type: 'array' };
    fileName: string = 'SheetJS.xlsx';
    showData: boolean = false;

    public dropped(event: UploadEvent) {
       this.files = event.files;
       for (const droppedFile of event.files) {
         if (droppedFile.fileEntry.isFile) {
           const reader: FileReader = new FileReader();
           const fileEntry = droppedFile.fileEntry as FileSystemFileEntry;
           fileEntry.file((file: File) => {
              var filePath = file;
             reader.onload = (e: any) => {
              const bstr: string = e.target.result;
              const wb: XLSX.WorkBook = XLSX.read(bstr, {type: 'binary'});
              const wsname: string = wb.SheetNames[0];
              const ws: XLSX.WorkSheet = wb.Sheets[wsname];
              this.data = <AOA>(XLSX.utils.sheet_to_json(ws, {header: 1}));
            };
            reader.readAsBinaryString(file);
            this.showData = true;
            this.infoModal.hide();
          });
       } else {
          this.showData = false;
          const fileEntry = droppedFile.fileEntry as FileSystemDirectoryEntry;
       }
     }
   }

  showPopUp(){ 
     console.log('yes');
  }
}

Ниже приводится мой component.htm

      <div class="modal-body">
        <file-drop id="infoFileModal" headertext="Drop files here" (onFileDrop)="dropped($event)" (onFileOver)="fileOver($event)" (onFileLeave)="fileLeave($event)"></file-drop>
      </div>

 <div class="card-body">
   <div *ngIf="showData" class="upload-table  table-responsive">
     <table #table class="table-bordered table-striped" id="dest_table" (load)="showPopup()">
        <tr *ngFor="let row of data">
           <td *ngFor="let val of row">
              {{val}}
           </td>
        </tr>
     </table>
  </div>
  <div *ngIf="!showData" class="div-upload">
     No Data Found
  </div>
 </div>

Ответы [ 3 ]

0 голосов
/ 30 апреля 2018

Вы можете подписаться на onloadend () - метод FileReader. Пожалуйста, посмотрите на прокомментированную часть кода.

 public dropped(event: UploadEvent) {
     this.files = event.files;
     for (const droppedFile of event.files) {
       if (droppedFile.fileEntry.isFile) {
         const reader: FileReader = new FileReader();
         const fileEntry = droppedFile.fileEntry as FileSystemFileEntry;
         fileEntry.file((file: File) => {
            var filePath = file;
           reader.onload = (e: any) => {
            const bstr: string = e.target.result;
            const wb: XLSX.WorkBook = XLSX.read(bstr, {type: 'binary'});
            const wsname: string = wb.SheetNames[0];
            const ws: XLSX.WorkSheet = wb.Sheets[wsname];
            this.data = <AOA>(XLSX.utils.sheet_to_json(ws, {header: 1}));
          };
          reader.readAsBinaryString(file);

          // subscribe to the onloadend()-method here
          reader.onloadend = (e) => {
            this.showPopUp();
          };

          this.showData = true;
          this.infoModal.hide();
        });
     } else {
        this.showData = false;
        const fileEntry = droppedFile.fileEntry as FileSystemDirectoryEntry;
     }
   }
 }

 showPopUp(){ 
    console.log('yes');
 }
0 голосов
/ 30 апреля 2018

Хорошо, вот другой подход.

Поскольку на рендеринг вашей таблицы уходит несколько минут, после заполнения массива данных ваш единственный шанс - прослушивать событие изменения столько времени, сколько потребуется. Чтобы предотвратить запуск метода showPopUp () при каждой завершенной итерации, вы используете Observable.debounceTime (), который вызывает метод, только если время, прошедшее после последнего события изменения, больше, чем указанное время в миллисекундах.

Компонент

import { Component, OnInit, OnDestroy, ViewChild, AfterViewInit} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import {Subscription} from "rxjs/Subscription";

 @ViewChild('table') table: any;
 private timer= Observable.timer(1000); // wait one second before calling the method
 private subscription: Subscription;

 ngOnDestroy(): void {
    if(this.subscription){
        this.subscription.unsubscribe();
    }
 }

public dropped(event: UploadEvent) {
        // ...

        reader.readAsBinaryString(file);
        this.showData = true;
        this.infoModal.hide();

        // call the watcher with a delay of one second
        // in order to give angular enough time to build up the table
        this.subscription = this.timer.subscribe( () => {
            this.triggerTableWatcher();
        });

        // ...

}


triggerTableWatcher() {
    // define the object to listen to
    const trigger = this.table.changes();

    // define the debounce-time (adjust it, if it doesn't fit your needs)
    const debounceAt = trigger.debounceTime(1000);

    // subscribe to the trigger and tell which method to call eventually
    debounceAt.subscribe(() => this.showPopUp());
}

HTML-шаблон (только его важная часть)

<div class="card-body">
   <div *ngIf="showData" class="upload-table  table-responsive">
      <table #table class="table-bordered table-striped" id="dest_table">
         <tr *ngFor="let row of data">
              <td *ngFor="let val of row">
                {{val}}
             </td>
         </tr>
     </table>
</div>
0 голосов
/ 30 апреля 2018

В собственной таблице нет события load. Эта логика должна быть делегирована службе, которая загружает данные.

Или, как предлагается в комментарии, вы можете использовать ngAfterViewInit(). Но: если таблица была впервые обработана и вы загружаете данные, она не будет работать

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...