The title is not very explanatory, but I couldn't find any better way to phrase my problem.
I'm working with angular, and I've been facing a problem a few times now. Let me show it as an example :
Let's say I have a mother component MomComponent
, which contains multiple KidComponent
.
Each KidComponent
can be resized by the user. If that happens, all of the other kids should be resized as well.
A Kid component should also be able to live without siblings.
Here's my code :
// mom.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-mom',
templateUrl: './mom.component.html',
})
export class MomComponent {
width: number;
}
<!-- mom.component.html -->
<app-kid [(width)]="width"></app-kid>
<app-kid [(width)]="width"></app-kid>
<app-kid [(width)]="width"></app-kid>
// kid.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-kid',
templateUrl: './kid.component.html',
})
export class KidComponent {
@Input() set width(w: number) {
this._width = w;
this.draw();
}
@Output() widthChange = new EventEmitter<number>();
private _width = 100;
onUserResize(newWidth: number) {
this.widthChange.emit(newWidth);
this._width = newWidth;
this.draw();
}
draw() {
// Drawing code
}
}
My problem here, is that the kid which has been resized will be drawn 2 times. One first time because I call it internally, and a second time because the mom's variable width
will be updated.
I could change my kid component as follows, so that it's only redrawn from external change :
// kid.component.ts
export class KidComponent {
// [...]
onUserResize(newWidth: number) {
this.widthChange.emit(newWidth);
// I remove these 2 lines:
//
// this._width = newWidth;
// this.draw();
}
// [...]
}
But then, I also want to be able to use my KidComponent
on its own without sharing its width with other kids (just <app-kid></app-kid>
), in which case, the above code wouldn't work.
The only solution that I can think of right now is the following :
// kid.component.ts
export class KidComponent {
// [...]
onUserResize(newWidth: number) {
this.widthChange.emit(newWidth);
if (!this.widthChange.observers.length) {
// No-one is listening to the event, I redraw myself
this._width = newWidth;
this.draw();
} else {
// Someone is listening to my resize, let's hope they
// take care of redrawing me...
}
}
// [...]
}
But I don't really like this approach, the fact that there is an observer on the widthChage
emitter doesn't mean that this observer will redraw the KidComponent
.
So, my question is : Is there a better approach that I'm missing?
Thanks!
Aucun commentaire:
Enregistrer un commentaire