我的视图无法使用Angular5组件中的更新数据进行更新

时间:2018-03-19 20:33:10

标签: angular angular5

我的观点有一些简单的代码:

  HERE{{ files.length }}THERE
  <div class="uploaded-files" *ngIf="files.length > 0">
    <div class="uploaded-files-title">
      <h4>Selected Files</h4><h5>&nbsp;(X)</h5>
    </div>
    <table class="table">
      <thead class="thead-dark">
      <tr>
        <th scope="col">File Name</th>
        <th scope="col">File Size</th>
        <th scope="col" class="text-center">Upload Status</th>
        <th scope="col" class="text-center"><a href="" (click)="removeAll($event)">Remove All</a></th>
      </tr>
      </thead>
      <tbody>
        <tr *ngFor="let file of files">
          <td>{{ file.relativePath }}</td>
          <td>{{file.size}}</td>
          <td class="text-center"><i class="mdi mdi-check-circle mdi-24px approved"></i></td>
          <td class="text-center"><i class="mdi mdi-delete mdi-24px actions"></i></td>
        </tr>

我的组件是:

import {
  Component,
  OnInit
} from '@angular/core';
import { UploadEvent, UploadFile, FileSystemFileEntry  } from 'ngx-file-drop';


@Component({
  selector: 'upload-modal',  // <upload-modal></upload-modal>
  providers: [
  ],
  styleUrls: [ './upload.component.scss' ],
  templateUrl: './upload.component.html'
})
export class UploadComponent implements OnInit {


  constructor() {
  }

  public files: UploadFile[] = [];

  public ngOnInit() {
  }

  dropFile(event) {
    let droppedFiles: UploadFile[] = []
    if(this.files.length === 1) {
      return
    }

    const fileEntry = event.files[0].fileEntry as FileSystemFileEntry;
    fileEntry.file(fileData => {
      console.log('before', this.files)
      this.files.push({
        name: fileEntry.name,
        size: fileData.size
      })
      console.log('after', this.files)
    })
  }

  handleFileInput() {
    alert('files')
  }

  removeAll(event) {
    event.stopPropagation()
    this.files: UploadFile[] = []
  }

}

当我的组件dropFile功能执行其操作时,console会正确打印出来,但视图没有任何更新的文件。

我正在使用angular 5.2.0。我做错了什么?

4 个答案:

答案 0 :(得分:2)

我认为Angular并不知道你在幕后改变了模型。

默认情况下,Angular使用zones在异步事件后触发它的更改检测机制 - 虽然这对于您将遇到的大多数异步事件都可以正常工作,但Angular,Zone.js使用的区域实现仅支持少数非标准API而FileSystemFileEntry不是one of them。在这种情况下,最好的办法是手动触发变更检测,如here所述。

答案 1 :(得分:1)

您可以使用更改检测手动检测更改。我不建议在所有情况下都使用这种方法,但在这一方面,这可能是最好的方法。

将ChangeDectorRef添加到导入语句

import {
  Component,
  OnInit,
  ChangeDetectorRef 
} from '@angular/core';

然后将其添加到构造函数

constructor(private cd: ChangeDetectorRef) {}

然后在删除文件后,您可以使用更改检测器来触发更改检测。

dropFile(event) {

  // add this to the end of the dropFile method
  this.cd.detectChanges();
}

答案 2 :(得分:0)

更改检测器必须是user4091335指出的回调的最后一行,而不是droppped file方法的最后一行。

dropped(event: any) {
    for (const droppedFile of event.files) {
      const fileEntry = droppedFile.fileEntry as FileSystemFileEntry;
      fileEntry.file((file: File) => {
        this.files.push(file);
        **this.ref.detectChanges();**
      })
    }
  }

答案 3 :(得分:0)

我在尝试更新视图时遇到了同样的问题,因此我解决了使用Promise而不是使用ChangeDetectorRef检测视图上的更改的问题。像魅力一样工作。 这是我的解决方法

    triggerUpload(evt:UploadEvent){    


    let files = evt.files;
    let self = this;
    this.fillupFiles(files).then(function(response){
       self.uploadAndRender();          
    });

  }

fillupFiles(files):Promise<Object>{
    let self = this;
    let promise = new Promise(function(resolve, reject){
      var count = files.length;
      var index = 0;
      for(let droppedFile of files){
        if(droppedFile.fileEntry.isFile){
          let fileEntry = droppedFile.fileEntry as FileSystemFileEntry;
          fileEntry.file((file:File)=>{
            index++;
            self.files.push(file);
            if(index==count){
              resolve(true);
            }
          });
        }
      }
    });

    return promise;
  }