To improve your project, I recommend incorporating a view-model concept. A view-model contains data on how to display a specific model. For this scenario, consider passing something like Array<ImageViewModel>
between components A
and B
. You can transmit this data through a service if it fits your requirements, or utilize a parent component, such as:
Template of the parent component:
<component-a [images]="images" *ngIf="active === 'a'" (onImageSelected)="handleImageSelected($event)"></component-a>
<component-b [images]="images" *ngIf="active === 'b'" (onSettingsEditCompleted)="handleSettingsEditCompleted()"></component-b>
Code of the parent component:
.... {
images: Array<ImageViewModel> = [];
active: string = "a";
constructor(private _service: ImageService) {
// Assume that the service returns an array of image URLs.
this._service.fetchImages().subscribe((urls) => {
this.images = urls.map(url => ({src: url, disabled: true}));
if (this.images.length > 0) {
this.images[0].disabled = false;
}
});
}
handleImageSelected(image: ImageViewModel) {
this.active = "b";
console.log("Image selected", image);
}
handleSettingsEditCompleted() {
this.active = "a";
}
}
Define ImageViewModel
as follows:
interface ImageViewModel {
src: string;
disabled: boolean;
}
In componentA
, employ the [ngClass]
directive to modify image availability.
Template of ComponentA:
<img *ngFor="let image of images" [src]="image.src" [ngClass]="{'not-opened': image.disabled}" (click)='!image.disabled && handleImageSelected(image)'/>
Styles for ComponentA:
.not-opened {
filter: grayscale(85%); // Consider using non-WebKit version as well.
-webkit-filter: grayscale(85%);
}
Code for ComponentA:
... {
@Output()
onImageSelected = new EventEmitter<ImageViewModel>();
@Input()
images: Array<ImageViewModel> = [];
handleImageSelected(image: ImageViewModel) {
this.images[1].disabled = false;
this.onImageSelected.emit(image);
}
}
If anything is unclear, refer to the Angular documentation to understand @Input
and @Output
annotations.