使用Angular v2.4.8和PrimeNg v1.1.4
我有一个包含两个组件的页面:
我将Dropzone配置为一次发送5个文件,当完成5个文件时,会引发事件onDropZoneSendingMultiple
。上传所有文件后,会引发onDropZoneQueueComplete
。
在两个侦听器中,我想刷新第二个组件中的数据表。这不起作用。我需要刷新页面才能看到新文件。
我的主页HTML:
<div class="row" id="dropzoneContainer">
<dropzone class="dropzone" #dz [config]="dropZoneConfig"
(error)="onDropZoneUploadError($event)"
(sendingmultiple)="onDropZoneSendingMultiple($event)"
(queuecomplete)="onDropZoneQueueComplete($event, dz);"
(maxfilesreached)="onDropZoneMaxfilesReached($event)"
(maxfilesexceeded)="onDropZoneMaxfilesExceeded"></dropzone>
</div>
<div class="row">
<div class="col-md-12">
<FilesList></FilesList>
</div>
</div>
Dropzone
- 组件显示了dropzone。 FilesList
显示数据表。
HTML的一部分:
<p-dataTable [hidden]="loading" [value]="files" selectionMode="single" (onRowSelect)="details($event)">
在我的主要ts文件中,我有:
@ViewChild(FilesListComponent)
public filesListComponent: FilesListComponent;
private reloadFileList() {
this.filesListComponent.reload();
}
在我的文件列表中我有
public files: File[];
public reload() {
this.getFiles();
}
public getFiles() {
this.fileService.getAll()
.then(
data => {
this.files = data;
});
}
在页面加载时也会调用 getFiles
。
当我添加console.log()
语句时,我可以看到getFiles()
已被调用,this.files
已更新,但表格未刷新。
答案 0 :(得分:16)
对于仍在寻找将记录添加到绑定到primeng表的数组的新语法的人
this.arrayRecords= [...this.arrayRecords, newObject];
答案 1 :(得分:9)
更新:PrimeNG最近删除了自动检测更改的DoCheck界面,请参阅:https://www.primefaces.org/primeng-4-0-0-rc4-released/
答案是使用扩展运算符([... arr] - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator)将项添加到数组而不是.push()。
原始答案:我遇到了一个类似的问题,我使用稍微不同的方法解决了这个问题。如果您使用相同的服务上传和检索文件,则可以使用RxJS而不是跨组件监听事件。
在我的服务上,当我使用POST或PUT时,我想在应用程序中重新加载:
private _shouldUpdateSource = new BehaviorSubject<boolean>(false);
shouldUpdateObservable = this._shouldUpdateSource.asObservable();
在POST和/或PUT方法中
this.http.post(..).map( res => {this._shouldUpdateSource.next(true);});
允许您订阅组件中的fileService.shouldUpdateObservable:
this.shouldUpdateSub = this.fileService.shouldUpdateObservable
.subscribe((shouldUpdate: boolean) => {
if (shouldUpdate) {
this.updateFiles();
}
});
这似乎是处理我见过/使用的组件之间的服务通信的最佳方式。
CNC中
这是官方文件中的相同概念:
https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service
-Edit 2- 更新到4.0.0后,我再次遇到此问题。 FWIW,我最终删除了PrimeNG Datatable,而不是使用手册* ngFor,它工作正常。似乎PrimeNg文档(https://www.primefaces.org/primeng/#/datatable)告诉您:
“例如,在删除项目时使用切片而不是拼接,或者在添加项目时使用扩展运算符而不是push方法。”
我不确定他们为什么要求你这样做,因为它与官方Angular文件告诉你要做的事情相反,但我认为它与为什么[value]绑定无法正常工作有关
就个人而言,我正在离开PrimeNg,转而使用具有显式refresh()函数的Covalent数据表:https://teradata.github.io/covalent/#/components/data-table
答案 2 :(得分:5)
<强>更新强>:
我更好地了解了the documentation的p-dataTable,特别是标题为“变化检测”的部分。我删除了[immutable]=false
标记中的p-dataTable
属性,而我现在通过在修改基础数组时返回类似的内容来刷新表:
return myOriginalArray.slice();
<强> ORIGINAL 强>:
当我从用于填充表格的基础数组中删除项目时,我遇到了p-datatable
更新/刷新的问题。不知道为什么,但为p-datatable
标签添加以下属性为我解决了问题:
[immutable]=false
我使用的是PrimeNG ^ 4.1.3
答案 3 :(得分:1)
我怀疑这与您的子组件处理更改的方式有关。您应该实现onChange事件并以这种方式设置文件。这是一个例子:
```
export class FilesListComponent implements OnChanges {
@Input() files: File[];
ngOnInit() {
}
// Subscribe to the change event and update the model
ngOnChanges(changes: {[propName: string]: SimpleChange}) {
let key = 'files';
this.files = changes[key].currentValue;
}
}
```
答案 4 :(得分:0)
我们可以标记视图以进行检查和呼叫检测。
@ViewChild('searchDt') searchTable: DataTable;
self.dealService.getAccounts(self.searchParams).subscribe((response) => {
Deal.setAvailableAccount(response.map((current) => {
return {
"cifNumber": current['cif'],
"ucic": current['ucic'],
"accountNomenclature": current['customerName'],
}
}));
**self.searchTable.changeDetector.markForCheck();
self.searchTable.changeDetector.detectChanges();**
});
答案 5 :(得分:0)
对于面临同样问题的新人。我通过将 p 表(或 p 数据表)移动到一个单独的组件并使该组件的实例化依赖于一个变量来解决它。示例:
<p-dialog [(visible)]="loading">
<innercomponent *ngIf="loading"> <!-- contains the p-table -->
</innercomponent>
</p-dialog>
以帖子为例,我们可以移动条件[hidden]="loading"
<p-dataTable [hidden]="loading" ...>
到了之前的包装组件的层次,思路是销毁并重新创建组件,以便刷新表数据