I have my app.component
with a list of objects
class Hero {
alias: string;
constructor(public firstName: string,
public lastName: string) {
}
}
class AppComponent {
...
heroes: Hero[] = [
new Hero("foo", "bar")
];
...
onHeroChange($event: Hero, index: number): void {
this.heroes[index] = $event;
}
<div *ngFor="let hero of heroes; let index=index">
<hero [hero]="hero" (heroChange)="onHeroChange($event, index)"></hero>
</div>
The HeroComponent is
export class HeroComponent {
@Input()
set hero(newValue: Hero) {
this._hero = newValue;
this.showAlias = !!newValue.alias;
}
get hero(): Hero {
return this._hero;
}
@Output() heroChange: EventEmitter<Hero> = new EventEmitter<Hero>();
showAlias: boolean = !1;
private _hero: Hero;
//
@HostListener('click')
onHeroClick(): void {
this.hero.alias = `alias_${+new Date()}`;
console.info('HERO TO EMIT', this.hero);
this.heroChange.emit(this.hero);
}
}
My problem is that even by assigning the changed hero in app.component
, the set hero
inside hero.component
is not called, so showAlias
in the example is not updated and I don't see the alias in the hero.component
.
Do I need to force the ngFor by assigning the entire array?
Maybe a workaround could be removing the object from the array and then inserting again? Sounds like useless computation though.
Note: this is just an example, it's not what I'm really working on, so something like
Update the showAlias prop in the onHeroClick method
or
Assign hero in the hero.component
unfortunately don't solve the issue. I need the changes to be on the outside because other stuff happens.
Could be another option changing the detection to onPush
and marking for check manually?
You're not setting a new hero
, you're just modifying a property on the existing one:
this.hero.alias = `alias_${+new Date()}`;
That doesn't fire the setter. Change the line like this:
this.hero = {...this.hero, alias: `alias_${+new Date()}`};