[英]My View won't update with updated data from my Angular5 component
My view has some simple code: 我的观点有一些简单的代码:
HERE{{ files.length }}THERE
<div class="uploaded-files" *ngIf="files.length > 0">
<div class="uploaded-files-title">
<h4>Selected Files</h4><h5> (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>
My component is: 我的组件是:
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[] = []
}
}
When my component's dropFile
function does what it does, the console
prints out correctly, but the view doesn't have any updated files. 当我的组件的
dropFile
函数执行其操作时, console
将正确打印出,但视图中没有任何更新的文件。
I'm using angular 5.2.0
. 我正在使用
angular 5.2.0
。 What am I doing wrong? 我究竟做错了什么?
I think Angular's not aware of you having changed the model behind the scenes. 我认为Angular尚未意识到您已经更改了幕后模型。
By default, Angular uses zones to trigger it's change detection mechanism after async events—although this works fine for most async events you'll encounter, the zone implementation used by Angular, Zone.js, only supports a handful of non-standard APIs and FileSystemFileEntry isn't one of them . 默认情况下,Angular在异步事件后使用区域来触发其更改检测机制—尽管这对于您将遇到的大多数异步事件都很好,但是Angular,Zone.js使用的区域实现仅支持少数非标准API,并且FileSystemFileEntry不是其中之一 。 In cases like this, your best bet is to manually trigger the change detection as explained here .
在这样的情况下,最好的办法是手动触发变化检测作为解释在这里 。
You can manually detect changes using the change detection. 您可以使用更改检测手动检测更改。 I don't recommend using this method in all situations but in this one it's probably the best way.
我不建议在所有情况下都使用此方法,但是在这种情况下,这可能是最好的方法。
Add ChangeDectorRef to the import statement 将ChangeDectorRef添加到导入语句
import {
Component,
OnInit,
ChangeDetectorRef
} from '@angular/core';
then add it to your constructor 然后将其添加到您的构造函数中
constructor(private cd: ChangeDetectorRef) {}
Then after you drop the files you can use the change detector to trigger change detection. 然后,在删除文件后,您可以使用更改检测器触发更改检测。
dropFile(event) {
// add this to the end of the dropFile method
this.cd.detectChanges();
}
The change detector needs to be the last line of the callback as user4091335 pointed out and not the last line of the droppped file method. 更改检测器必须是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();**
})
}
}
I had the same issue trying to update the view, and I solved using promises instead of detecting the changes on the view using ChangeDetectorRef. 我在尝试更新视图时遇到了同样的问题,因此我解决了使用Promise而不是使用ChangeDetectorRef在视图上检测更改的问题。 Worked like a charm.
像魅力一样工作。 Here's my solution
这是我的解决方案
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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.