用* ng加载微调框如果在执行函数期间未显示

时间:2019-09-17 03:40:37

标签: javascript angular typescript

如果在执行功能时尝试显示加载微调器。我已经尝试过其他方法,但是微调框不会显示。

这是HTML:

<div class="row pt-3" id="firstRow">
 <div class="col">
  <button class="btn btn-dark back-button">
   <fa name="upload"></fa>
   <span>Load .csv file</span>
  </button>
  <input type="file" #fileImportInput name="File Upload" class="txtFileUpload p-3" (change)="fileChangeListener($event)" accept=".csv" />
    <img class="spinner" *ngIf="loading" src="../../../assets/img/gif-spinner/Spin-2s-200px.gif" />
 </div>
</div>

这是TS代码的一部分

export class MotionAnalysisComponent implements OnInit {
loading = false;

 fileChangeListener($event: any): void {
   this.loading = true;

   let files = $event.srcElement.files;

   if (this.isCSVFile(files[0])) {
    let input = $event.target;
    let reader = new FileReader();
    reader.readAsText(input.files[0]);

    reader.onload = () => {
     let csvData = reader.result;
     let csvRecordsArray = (<string>csvData).split(/\r\n|\n/);
     this.csvRecords = this.getDataRecordsArrayFromCSVFile(csvRecordsArray, 4);
   };

   reader.onerror = function () {
    alert('Unable to read ' + input.files[0]);
   };
  } else {
    alert("Please import valid .csv file.");
    this.fileReset();
  }

   this.loading = false;

如果我在函数中注释掉“ this.loading = false”,则微调器将在函数执行后显示,并且(显然)不会消失。那么,如何使HTML理解在功能执行期间应该显示微调框?

4 个答案:

答案 0 :(得分:1)

要让微调器有时间初始化,可以在将loading设置为true之后异步运行代码。这可以通过将代码移到setTimeout回调内部来实现。 loading属性应在该回调方法的结尾处​​重置。

fileChangeListener($event) {
  this.loading = true;                    // First, set loading property
  setTimeout(() => {                      // Call setTimeout to run code asynchronously
    let files = $event.srcElement.files;
    if (this.isCSVFile(files[0])) {
      ...
    } else {
      ...
    }
    this.loading = false;                 // Reset loading before leaving callback method
  }, 0);
}

有关演示,请参见this stackblitz。请注意,如有必要,您可以增加setTimeout延迟(在上面的示例中将其设置为0毫秒)。

答案 1 :(得分:0)

我的猜测是

... other part of the function...

是对可观察或异步函数的调用,因此您的

this.loading = false;

被立即称为

我不知道该代码块到底是什么,但很可能您需要一个回调函数,以在异步调用完成后将加载设置为false。

答案 2 :(得分:0)

@Component({
  selector: 'm-selector',
  templateUrl: './selector.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush, <-- add this line
  styleUrls: ['./selector.component.scss']
})

添加更改检测方法

然后在您的构造函数中

constuctor(
...,
private ref: ChangeDetectorRef <-- add this line
){ }

这使您可以要求角度手动检查更改

然后您可以使用它,例如:

this.loading = true
this.ref.markForCheck()

每次使用*ngIf更改影响HTML的变量时,调用ref.markForCheck

这样,您将节省更少的内存,因为您无需继续收听某个变量

但是如果您的变量经常随时间变化,那么建议使用监听器

答案 3 :(得分:0)

  1. 似乎有必要查看调试信息。因此,在HTML中显示loading的值:

                                           加载.csv文件                  

     <p>loading {{ loading  }} </p>
    
     <img class="spinner" *ngIf="loading" 
        src="../../../assets/img/gif-spinner/Spin-2s-200px.gif" />
    </div>
    

如果看到的话,loading的值会正确更新,然后尝试设置样式:

img { 
     width: inherit; 
     height: inherit; 
     position: fixed; 
     top:0; 
     left:0; 
}
  1. 是错字吗?您的div标签未正确结尾:/div>

更新:

尝试通过模板表达式设置图像的src

HTML:

<img class="spinner" 
     *ngIf="loading" 
     [src]="imagePath"/>

TypeScript:

imagePath = '../../../assets/img/gif-spinner/Spin-2s-200px.gif;'