}}} === abscomponent.component.html === {{{#!highlight xml

abscomponent works! {{message}}

{{h.name}}
{{value}}
}}} === abscomponent.component.ts === {{{#!highlight javascript import { Component, OnInit, Input } from '@angular/core'; import { TestData } from './testdata'; import { TableHeader } from './tableheader'; import { TableRow } from './tablerow'; @Component({ selector: 'app-abscomponent', templateUrl: './abscomponent.component.html', styleUrls: ['./abscomponent.component.css'] }) export abstract class AbscomponentComponent implements OnInit { @Input() message: string = "Message"; items: TestData[]; headers: TableHeader[]; rows: TableRow[]; constructor() { this.items = []; this.headers = []; this.rows = []; } ngOnInit(): void { } public configure(input: string, data: TestData[], header: TableHeader[], rows: TableRow[]): void { this.message = input; this.items = []; this.headers = []; this.rows = []; // on push detector data.forEach(element => { this.items.push(element); }); header.forEach(element => { this.headers.push(element); }); rows.forEach(element => { this.rows.push(element); }); console.log("configure called"); } } }}} === testdata.ts === {{{#!highlight javascript export interface TestData { name: string; } }}} === tableheader.ts === {{{#!highlight javascript export interface TableHeader { name: string; } }}} === tablerow.ts === {{{#!highlight javascript export interface TableRow { values: string[]; } }}} === conccomponent.component.ts === {{{#!highlight javascript import { Component, OnInit } from '@angular/core'; import { AbscomponentComponent } from '../abscomponent/abscomponent.component'; import { TestData } from '../abscomponent/testdata'; import { TableHeader } from '../abscomponent/tableheader'; import { TableRow } from '../abscomponent/tablerow'; @Component({ selector: 'app-conccomponent', templateUrl: '../abscomponent/abscomponent.component.html', //uses base class html styleUrls: ['../abscomponent/abscomponent.component.css'] // uses base class css }) export class ConccomponentComponent extends AbscomponentComponent implements OnInit { constructor() { super(); } ngOnInit(): void { let itemsx: TestData[]; itemsx = []; itemsx.push({ name: "concrete" }); itemsx.push({ name: "concreteaaa" }); itemsx.push({ name: "asd" }); let headers: TableHeader[]; let rows: TableRow[]; headers = []; headers.push({ name: "namea" }); headers.push({ name: "nameb" }); rows = []; rows.push({ values: ["x1", "y1"] }); rows.push({ values: ["x2", "y2"] }); rows.push({ values: ["x3", "y3"] }); rows.push({ values: ["x4", "y4"] }); rows.push({ values: ["x5", "y5"] }); rows.push({ values: ["x6", "y6"] }); rows.push({ values: ["x7", "y7"] }); rows.push({ values: ["x8", "y8"] }); this.configure(this.message + " extended !", itemsx, headers, rows); } } }}} == Angular change detection == * https://www.mokkapps.de/blog/the-last-guide-for-angular-change-detection-you-will-ever-need/ * https://angular.io/api/core/ChangeDetectorRef In short, the framework will trigger a change detection if one of the following events occurs: * any browser event (click, keyup, etc.) * setInterval() and setTimeout() * HTTP requests via XMLHttpRequest {{{#!highlight javascript constructor(private ref: ChangeDetectorRef) { //... } this.ref.detectChanges(); // trigger detection change }}}