尽管模型发生变化,Angular4 PrimeNG DataTable 仍未更新

标签 angular primeng-datatable

我从数据服务获取返回到 Web API 的可观察对象,该 API 返回数组并正确填充父组件中的数据表。我通过@Input 将用于填充数据表的数组传递给子组件。单击父组件上的一行时,我会显示一个使用表单编辑单行的模式。单击模态上的保存按钮时,行信息将发送到调用服务器并正确更新信息的子组件。服务器返回更新后的对象,然后将其拼接到@Input 数组中。数据表永远不会更新,尽管我可以看到对模型数组的更改确实发生并且由 Angular 通过使用 Augury 检测到。我试过使用 NgZone、NgOnChanges 和 setters/getters 强制更新数组,但无济于事。我在另一个项目中有完全相同的代码,它按预期工作。我不确定我在这里遗漏了什么。

父模板

<h2>Website Aliases</h2>

<p-dataTable #dt [value]="websiteAliases" selectionMode="single" [(selection)]="selectedWebsiteAlias"
             (onRowSelect)="onRowSelect($event);wad.setEditValue(selectedWebsiteAlias)"
             [paginator]="true" [rows]="100"
             [sortMode]="multiple">
    <p-header>
        Website Aliases
        <div style="float:right;">
            <button pButton type="button" (click)="wad.setCreateValue();" icon="fa-plus"></button>
            <button pButton type="button" (click)="reloadDataTable();" icon="fa-refresh"></button>
        </div>
    </p-header>
    <p-column field="aliasID" header="Alias ID" sortable="true"></p-column>
    <p-column field="webID" header="Web ID" [filter]="true" filterMatchMode="contains"></p-column>
    <p-column field="csHost" header="CsHost" [filter]="true" filterMatchMode="contains"></p-column>
</p-dataTable>

    <website-alias-detail #wad [websiteAlias]="selectedWebsiteAlias" [websiteAliases]="websiteAliases"></website-alias-detail>

父组件

import { Observable } from 'rxjs/Rx';
import { DataTableModule, DialogModule } from 'primeng/primeng';
import { WebsiteAliasDetailComponent } from './websitealiasdetails.component';

@Component({
    selector: 'website-alias',
    templateUrl: 'websitealias.component.html'
})

export class WebsiteAliasComponent {
    constructor(private dataService: DataService) { }
    private websiteAliases: WebsiteAlias[];
    private selectedWebsiteAlias: WebsiteAlias;


    ngOnInit(): void {
        this.dataService.get('websitealias').subscribe(apiObjects => this.websiteAliases = apiObjects);
    }

    onRowSelect(row): void {
        this.selectedWebsiteAlias = this.websiteAliases.find(websiteAlias => websiteAlias.aliasID === row.data.aliasID);
    }

    createWebsiteAlias(): void {
        this.selectedWebsiteAlias = null;
    }

    reloadDataTable(): void {
        this.dataService.get('websitealias').subscribe(apiObjects => this.websiteAliases = apiObjects);
    }
}

子模板

<p-dialog #dialog modal="true" header="Website Alias Details" [(visible)]="display">
    <form #form [formGroup]="alias">
        <div class="alert alert-danger" [hidden]="alias.controls.webID.valid || (alias.controls.webID.pristine && !submitted)">
            Web ID is required and only accepts numbers
        </div>
        <div class="alert alert-danger" [hidden]="alias.controls.csHost.valid || (alias.controls.csHost.pristine && !submitted)">
            CS Host is required
        </div>
        <div class="divTable">
            <div class="divTableBody">
                <div class="divTableRow" *ngIf="alias">
                    <div class="divTableCell"><label>Alias ID:  </label></div>
                    <div class="divTableCell"><label><input placeholder="Alias ID" formControlName="aliasID" readonly="readonly" /></label></div>
                </div>
                <div class="divTableRow">
                    <div class="divTableCell"><label>Web ID:  </label></div>
                    <div class="divTableCell"><input placeholder="Web ID" formControlName="webID" /></div>
                </div>
                <div class="divTableRow">
                    <div class="divTableCell"><label>CS Host:   </label></div>
                    <div class="divTableCell"><input placeholder="CS Host" formControlName="csHost" /></div>
                </div>
                <div class="divTableRow">
                    <div class="divTableCell">
                        <button pButton type="submit" label="Save" (click)="saveWebsiteAlias(alias.value)" [disabled]="alias.invalid" class="ui-button ui-button-primary"></button>
                        <button pButton type="button" label="Close" (click)="hideDialog();" class="ui-button ui-button-secondary"></button>
                        <button *ngIf="websiteAlias" pButton type="submit" label="Delete" (click)="deleteWebsiteAlias(alias.value)" class="ui-button ui-button-danger"></button>
                    </div>
                </div>
            </div>
        </div>
    </form>
</p-dialog>

子组件

import { Component, Input, Output, OnInit, ViewEncapsulation } from '@angular/core';
import { DataService } from '../../services/data.service';
import { WebsiteAlias } from './WebsiteAlias';
import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms';

@Component({
    selector: 'website-alias-detail',
    templateUrl: 'websitealiasdetails.component.html',
    encapsulation: ViewEncapsulation.None,

})

export class WebsiteAliasDetailComponent implements OnInit {
    @Input() websiteAliases: WebsiteAlias[];
    @Input() websiteAlias: WebsiteAlias;

    public alias: FormGroup;
    private api = 'websitealias';
    private display: boolean = false;
    private isEdited: boolean = false;

    constructor(private dataService: DataService, private formBuilder: FormBuilder) { }

    ngOnInit(): void {
        this.alias = this.formBuilder.group({
            aliasID: [''],
            webID: ['', [Validators.required, Validators.pattern('[0-9]*')]],
            csHost: ['',Validators.required]
        });

    }


    setEditValue(websiteAlias: WebsiteAlias)
    {
        this.alias.patchValue({ aliasID: websiteAlias.aliasID, webID: websiteAlias.webID, csHost: websiteAlias.csHost});
        this.isEdited = true;
        this.showDialog();
    }

    setCreateValue()
    {
        this.alias.patchValue({ aliasID: '', webID: '', csHost: '' });
        this.isEdited = false;
        this.websiteAlias = null;
        this.showDialog();
    }


    showDialog(): void {

        this.display = true;
    }

    hideDialog(): void {
        this.display = false;
    }

    saveWebsiteAlias(savedAlias: WebsiteAlias): void {

        if (!this.isEdited)
            this.createWebsiteAlias(savedAlias);            
        else {
            this.editWebsiteAlias(savedAlias);
        }

        this.hideDialog();
    }

    deleteWebsiteAlias(deletedAlias: WebsiteAlias): void {

        var idToDelete = 0;
        this.dataService.delete(this.api, deletedAlias.aliasID).subscribe(deletedId => idToDelete = deletedId);

        let websiteAliasToRemove = this.websiteAliases.find(web => web.aliasID === idToDelete);
        let index: number = this.websiteAliases.indexOf(websiteAliasToRemove);
        this.websiteAliases.splice(index, 1);

        this.hideDialog();

    }

    createWebsiteAlias(createdAlias: WebsiteAlias): void {

        var newAlias = new WebsiteAlias(0, createdAlias.webID, createdAlias.csHost);

        this.dataService.post(this.api, newAlias).subscribe(apiObject => newAlias.aliasID = apiObject.aliasID);

        this.websiteAliases.push(newAlias);
        this.websiteAlias = newAlias;

    }

    editWebsiteAlias(updatedAlias: WebsiteAlias): void {
        var idToUpdate = 0;
        var aliases = this.websiteAliases;
        this.dataService.put(this.api, updatedAlias).subscribe(apiObject => this.websiteAlias = apiObject);
        let websiteAliasToEdit = aliases.find(web => web.aliasID === updatedAlias.aliasID);
        let index: number = aliases.indexOf(websiteAliasToEdit);
        this.websiteAliases.splice(index, 1, updatedAlias);
    }

}

最佳答案

查看 [ How to programmaticaly trigger refresh primeNG datatable when a button is clicked 中给出的答案问题:1

我没有足够的代表将其添加为评论,但答案涉及使用 *ngIf 创建一个“可见”变量以触发重新创建 DOm。

关于尽管模型发生变化,Angular4 PrimeNG DataTable 仍未更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43809435/

相关文章:

angular - 我是否必须取消订阅 ActivatedRoute(例如 params)可观察量?

angular - 如何使用行分组对 PrimeNG DataTable 中的数据进行排序

angular - 如何防止点击行中的一列 - primeNG 数据表?

angular - Angular2 中的文件内容

javascript - 通过 Object.assign 在 Typescript 类中扩展 `this`

javascript - Angular/Ionic - 代码暴露会导致什么问题?

angular - 如何聚焦具有 ngif 的 TextArea

angular - 如何(以编程方式)预设 primeng 数据表中的过滤器值

html - 更新记录时如何动态更新行背景颜色?