1

Я создал компонент таблицы, который генерирует таблицу на основе конфигурации, которую я передаю. Я знаю, что есть, вероятно, лучшие способы написания повторно используемого компонента, но на данный момент это то, что у меня есть.Угловой 2 дочерний компонент, не обновляющийся при изменении источника данных

В основном компонент принимает конфигурацию с столбцами и источником данных, а затем сопоставляет столбцы с свойствами в источнике данных.

Моя проблема заключается в том, что в какой-то момент я внести изменения в один из источников данных таблицы, я первый пустой массив для экземпляра ...

this.members.datasource = [] 

затем я нажимаю новые данные на источник данных, как это. ..

for (let member in members) { 
      this.members.datasource.push(members[member]); 
} 

Моя проблема заключается в том, что когда я делаю это таблица не обновляется с новыми данными в источнике данных.

Я использовал функцию ngDoCheck в своем компоненте, и она действительно срабатывает при изменении источника данных, но больше ничего не происходит.

Здесь все относительно кода и разметки ...

IP-DataTable компонент

import { Component, Input, Output, OnInit, EventEmitter, ElementRef, DoCheck } from "@angular/core"; 

import { ITable } from "./interfaces/index"; 

@Component({ 
    selector: "ip-datatable", 
    templateUrl: "./ip-dataTable.component.html" 
}) 
export class IpDataTableComponent implements OnInit, DoCheck { 
    @Input() 
    public config: ITable; 
    public tableData: any; 

    @Output() 
    private onRowClick = new EventEmitter(); 

    constructor(private elem: ElementRef) { 

    } 

    public ngOnInit() { 
     // TODO: Decide whether or not to make this more dynamic (ie: excepts functions returning things other than a promise) 
     if (typeof (this.config.datasource) == "function") { 
      this.config.datasource() 
       .then((data: any) => { 
        this.tableData = data; 
       }); 
     } else { 
      this.tableData = this.config.datasource; 
     } 
    } 

    public rowClicked(e:Event) { 
     this.onRowClick.emit(e); 
    } 

    public ngDoCheck() { 

    } 
} 

В IP-DataTable компонента шаблон HTML

<table class="table table-bordered table-hover"> 
    <thead> 
    <tr> 
     <td *ngFor="let column of config.columns">{{column.header}}</td> 
    </tr> 
    </thead> 
    <tbody> 
    <tr 
     *ngFor="let item of tableData" 
     [class]="(config.rowConfig !== undefined) ? config.rowConfig.classes : ''" 
     (click)="rowClicked($event)" [id]="(item.id !== undefined) ? item.id : ''"> 
     <td *ngFor="let column of config.columns">{{item[column.mapKey]}}</td> 
    </tr> 
    </tbody> 
</table> 

компонент, который использует IP-DataTable

import { Component, OnInit, AfterViewInit, ApplicationRef } from "@angular/core"; 
import { ActivatedRoute } from "@angular/router"; 
import { EngagementService } from "../../services/engagement.service"; 

import { EngagementEditModel } from "../../models/index"; 
import { ITable } from "../../core/components/ip-datatable/interfaces/index"; 

@Component({ 
    templateUrl: "engagement-context.component.html" 
}) 

export class EngagementContextComponent { 
    public id: string; 
    public engagementDetails: EngagementEditModel; 

    // Temporarily hardcode groups as there is only two available. 
    public groups: ITable = { 
     columns: [ 
      { 
       header: "Name", 
       mapKey: "name" 
      } 
     ], 
     rowConfig: { 
      classes: "clickable override" 
     }, 
     datasource: [ 
     { 
      name: "Owners" 
     }, 
     { 
      name: "Users" 
     }] 
    }; 

    public members: ITable = { 
     columns: [ 
      { 
       header: "Name", 
       mapKey: "name" 
      } 
     ], 
     datasource: [] 
    } 

    constructor(private engagementService: EngagementService, private route: ActivatedRoute, private appRef: ApplicationRef) { 
     this.id = route.snapshot.params["id"]; 
      this.engagementService.getEngagementEditDetailsById(parseInt(this.id)) 
      .then((data: EngagementEditModel) => { 
       this.engagementDetails = data; 
       console.log(this.engagementDetails); // tslint:disable-line 
      }); 
    } 

    public groupClicked(e: Event) { 
     // Get the element of the event 
     let elem: IEventElement = e.currentTarget; 
     // Get the name of the selected node 
     let groupName = elem.textContent.trim().toLowerCase(); 
     let members = (<any>this.engagementDetails)[groupName]; 

     interface IEventElement extends EventTarget { 
      textContent?: string; 
     } 

     this.members.datasource = []; 

     for (let member in members) { 
      this.members.datasource.push(members[member]); 
     } 
    } 
} 

HTML Использование в IP-DataTable

<div class="row"> 
     <div class="col-md-12"> 
      <section class="section"> 
       <div class="section-body"> 
        <h4 class="section-title">Groups</h4> 
        <ip-datatable 
         [config]="groups" 
         (onRowClick)="groupClicked($event)"> 
        </ip-datatable> 
       </div> 
      </section> 
     </div> 
     <div class="col-md-12"> 
      <section class="section"> 
       <div class="section-body"> 
        <h4 class="section-title">Members</h4> 
        <ip-datatable 
         [config]="members" 
        ></ip-datatable> 
       </div> 
      </section> 
     </div> 
    </div> 

ответ

2

Хорошо, так что моя проблема в том, что в ngOnInit Поручаю this.config.datasource переменной называется tableData. Ну, когда происходит изменение, он никогда не переназначается этой переменной, поэтому, вызывая функцию ngDoCheck, а затем назначая this.config.datasource для tableData, я получаю изменение, отраженное по своему желанию.

Учитывая, что я слышал о препятствиях производительности ngDoCheck, я могу сделать что-то еще, если я начну замечать недостатки производительности. Если бы кто-то мог дать некоторое представление об этом в комментариях, я был бы признателен.

+0

Не могли бы вы уточнить свой ответ на правильный код? –

+0

@MarkEllul Извините, это было так давно, с тех пор я потерял код. Если у вас возникли проблемы, не стесняйтесь обращаться ко мне. –

Смежные вопросы