Reputation: 155
what am i missing here? This is a simplified example of creating an Angular 18 base component and a heir component extending it. Both are standalone. All seems fine in that the heir component sees the base components properties and methods in this. override is required on base methods and properties. Changes to the variables done in either base or heir show up. My problem is the html in base doesn't seem to recognize any changes in the variables. Change the variables in either base or heir and the heir html responds. Not what I expected.
I create a base component QueryBaseComponent
name:string='nancy;
changeName(newName:string){
this.name = newName;
console.log(this.name);//shows liberace
}
onClick(event:any){
//always fires even if it is override in heir component
console.log('base');
}
html
<label>{{name}}</label> //always shows initial value of nancy, doesn't change
<button (click)="onClick($event)">hit me</button>
<ng-content select="[position=bottom]"></ng-content>
i extend the base component
export class QueryTextComponent extends QueryBaseComponent implements AfterViewInit
ngAfterViewInit(){
this.changeName('liberace');
}
override onClick(event:any){
//never gets hit
console.log('heir');
}
html
<app-query-base>
<div position="bottom">
<label>{{name}}</label> //shows nancy and then liberace
</div>
</app-query-base>
Upvotes: 1
Views: 63
Reputation: 57986
You need to notice, that when you use content projection. The methods inside the content actually still have the original scope that it was declared on. So the HTML inside base component will always call the base component methods.
Since you declared the HTML content(stuff inside app-query-base
on QueryTextComponent
, it will always have access to the methods of QueryTextComponent
.
The best solution is to simply move the button inside the QueryTextComponent
so that the chick will call the override method instead of the base method.
<app-query-base>
<div position="bottom">
<button (click)="onClick($event)">hit me</button>
<div><label>{{name}}</label> </div>
</div>
</app-query-base>
import { Component, AfterViewInit } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
@Component({
selector: 'app-query-base',
standalone: true,
template: `
<label>{{name}}</label>
<ng-content select="[position=bottom]"></ng-content>
`,
})
export class QueryBaseComponent {
name: string = 'nancy';
changeName(newName: string) {
this.name = newName;
console.log(this.name);
}
onClick(event: any) {
console.log('base');
}
}
@Component({
selector: 'app-root',
standalone: true,
imports: [QueryBaseComponent],
template: `
<app-query-base>
<div position="bottom">
<button (click)="onClick($event)">hit me</button>
<div><label>{{name}}</label> </div>
</div>
</app-query-base>
`,
})
export class App extends QueryBaseComponent implements AfterViewInit {
ngAfterViewInit() {
this.changeName('liberace');
}
override onClick(event: any) {
console.log('heir');
}
}
bootstrapApplication(App);
Upvotes: 0