javascript - Por qué no puedo obtener resultado del componente padre en Angular
Quiero que los componentes hijos en Angular separen la Tabla de Material (hijo) de otros elementos (padre), pero lo extraño es que parece que no puedo obtener datos del padre o que obtengo datos inicializados del padre y no puedo refrescarlos. Aquí está el código: primero, el archivo .ts del padre:
@Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.scss']
})
export class DashboardComponent implements OnInit{
ticketList: Ticket[] = [];
originalTicketList: Ticket[] = [];
filterAllForm: FormGroup;
labelList: string[];
homeLabelList: string[];
currentTicketId: string;
searchBy: string = '';
maxall : number = 100;
isLoading :boolean = true;
showRelatedTickets = true;
constructor(private ticket: TicketService,
private formBuilder: FormBuilder) { }
ngOnInit() {
this.filterAllForm = this.formBuilder.group({
startDate: [''],
endDate: ['']
});
this.getAllTicket();
}
get filterFormControls() { return this.filterAllForm.controls; }
getAllTicket() {
let queryParams = '';
console.log(this.currentTicketId) + " " + this.searchBy;
if (this.searchBy === 'id') {
queryParams = 'id=' + this.currentTicketId;
this.showRelatedTickets = true;
}else if(this.searchBy !== ''){
queryParams = this.searchBy + '=' + this.currentTicketId;
this.showRelatedTickets = false;
}
this.ticket.getAllTicket(queryParams).then((res: Ticket[]) => {
this.isLoading = false;
this.ticketList = res;
this.originalTicketList = this.ticketList;
});
}
searchTicket() {
this.isLoading = true;
this.getAllTicket();
}
}
el HTML padre así:
<div class="ticket-container">
<mat-card *ngIf="isLoading" class="mat-card-style">
<mat-progress-spinner color="primary" mode="indeterminate">
</mat-progress-spinner>
</mat-card>
<div *ngIf="showRelatedTickets">
<app-dashboard-related-tickets-table [tablesource]="ticketList">
</app-dashboard-related-tickets-table>
</div>
<div *ngIf="!showRelatedTickets">
<app-dashboard-non-related-tickets-table [tablesource]="ticketList">
</app-dashboard-non-related-tickets-table>
</div>
</div>
y hay dos hijos que puedes ver, uno es app-dashboard-related-tickets-table y otro es app-dashboard-non-related-tickets-table, tienen un formato diferente y se cambian mediante el botón showRelatedTickets. Aquí mostraré el primero, el archivo .ts del hijo (app-dashboard-related-tickets-table):
@Component({
selector: 'app-dashboard-related-tickets-table',
templateUrl: './dashboard-related-tickets-table.component.html',
styleUrls: ['./dashboard-related-tickets-table.component.scss']
})
export class DashboardRelatedTicketsTableComponent implements OnInit, AfterViewInit{
dataSource: any;
displayedDetailColumns = ['id', 'caseStatus', 'anchorPoint', 'findingSourceSystem','caseCreateTimestamp', 'resolvedBy', 'resolution', 'resolutionNote'];
maxall: number = 100;
@Input() tablesource: Ticket[];
@ViewChild(MatPaginator, {static: false}) paginator: MatPaginator;
@ViewChild(MatSort, { static: true }) sort: MatSort;
applyFilter(filterValue: string) {
this.dataSource.filter = filterValue.trim().toLowerCase();
}
constructor() { }
ngOnInit() {
console.log(this.tablesource);
this.dataSource = new MatTableDataSource(this.tablesource);
}
ngAfterViewInit(){
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
this.getPageSizeOptions();
}
getPageSizeOptions(): number[] {
if (this.dataSource.data.length>this.maxall){
return [20, 50, this.dataSource.data.length];
}else{
return [20, 50, this.maxall];
}
}
}
entonces el archivo child(app-dashboard-related-tickets-table) .html:
<table mat-table matTableExporter [dataSource]="dataSource" matSort class="mat-elevation-z8"
#exporter="matTableExporter">
<!-- Ticket Column -->
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="mat-column-id-source"> SIR ID </th>
<td mat-cell *matCellDef="let element" class="mat-column-id-source">
<a href='ticket/{{element.id}}'>{{element.id}}</a>
</td>
</ng-container>
<!-- Type Column event source -->
<ng-container matColumnDef="findingSourceSystem">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="mat-column-id-source"> Source </th>
<td mat-cell *matCellDef="let element" class="mat-column-id-source"> {{element.findingSourceSystem}} </td>
</ng-container>
<!-- Type Column Related Event count -->
<ng-container matColumnDef="anchorPoint">
<th mat-header-cell *matHeaderCellDef class="mat-column-related-ticket-num"> Related Cases </th>
<td mat-cell *matCellDef="let element" class="mat-column-related-ticket-num">
{{element.relatedVertices}} </td>
</ng-container>
<!-- Type Column event source -->
<ng-container matColumnDef="caseStatus">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="mat-column-case"> Case Status </th>
<td mat-cell *matCellDef="let element" class="mat-column-case"> {{element.caseStatus}} </td>
</ng-container>
<!-- Type Column event source -->
<ng-container matColumnDef="caseCreateTimestamp">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="mat-column-date"> Case Created </th>
<td mat-cell *matCellDef="let element" class="mat-column-date">
{{element.caseCreateTimestamp | date:'MMM d, y, h:mm:ss a'}}
</td>
</ng-container>
<ng-container matColumnDef="resolvedBy">
<th mat-header-cell *matHeaderCellDef class="mat-column-resolvedBy"> Resolved By </th>
<td mat-cell *matCellDef="let element" class="mat-column-resolvedBy"> {{element.resolvedBy}}
</td>
</ng-container>
<ng-container matColumnDef="resolution">
<th mat-header-cell *matHeaderCellDef class="mat-column-closeCode"> Close Code </th>
<td mat-cell *matCellDef="let element" class="mat-column-closeCode"> {{element.resolution}}
</td>
</ng-container>
<ng-container matColumnDef="resolutionNote">
<th mat-header-cell *matHeaderCellDef class="mat-column-closeNote"> Close Note </th>
<td mat-cell *matCellDef="let element" class="mat-column-closeNote"> {{element.resolutionNote}}
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<mat-paginator [pageSizeOptions]="getPageSizeOptions()" showFirstLastButtons></mat-paginator>
<button mat-raised-button (click)="exporter.exportTable('csv')" class="export-button">Export Results</button>
Entonces en el componente hijo, uso @input tablesource y muestro dataSource. pero el resultado es así:
El componente hijo parece cargado porque el botón de resultado de exportación ya está allí, pero la tabla no apareció. Solo quiero hacerlo
console.log(tablesource)
Tengo []
Este es el registro de la consola del navegador:
¿Alguna idea de lo que pasó?
Estaba tratando de reproducir aquí: https://stackblitz.com/edit/angular-hbzpvr pero lo siento, no soy bueno en Angular, así que no estoy seguro de cómo cargar el padre en la página.
Respuesta #1
Según la salida de su consola, usted usa tablesource en su componente hijo antes de que haya sido actualizado por el componente padre. En lugar de crear datasource en ngOnInit del componente hijo, defina la propiedad tablesource como un setter y cree datasource en ese setter:
@Input() set tablesource(value: Ticket[]) {
console.log(value);
this.dataSource = new MatTableDataSource(value);
}
Mira este stackblitz para una demostración.

