Is it feasible in Angular2 to add CSS to a component using a service?

I have a component named A containing 5 images. Out of the 5, only one image is in color and clickable, while the remaining 4 are greyed out using the CSS class below:

.not_opened{
  -webkit-filter: grayscale(85%);
}

The greyscale images are not clickable.

When I click on the first image, it transitions to another component called B (component A disappears, as it is a separate component) where I perform certain actions. After that, by clicking a button, I return back to component A. Everything remains unchanged, but I want to remove or modify the not_opened class from the second image to make it colored and clickable. Then, upon clicking the second image, I move to a third component called C, and so on for the subsequent images...

Is there a way to achieve this without creating multiple different components each with their own CSS stylesheets? Maybe through a service? Can you suggest any solution?

Answer №1

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.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The magic of jQuery when chaining AJAX callback functions

I have a centralized ajaxSuccess callback function that needs to initialize components from various AJAX calls across the project. Here is an example: $(document).ajaxSuccess(function (response, status, xhr) { initComponents(); }); For module-level a ...

Loading columns and data dynamically into an Angular 2 table

I am working on an HTML page where I need to create a dynamic table. The columns for this table are fetched from the server and stored in a component variable using the type any[]. The data in the table is also dynamic, meaning that during programming, I d ...

Updating the DOM using jQuery after receiving an AJAX response

I'm grappling with the most effective way to modify the DOM after receiving an AJAX response. I prefer to showcase the code rather than attempt to articulate my dilemma. // page contains several checkboxes $("input[type='checkbox']").live(& ...

Having trouble choosing files on Mobile devices, whether it's IOS or Android

I'm having trouble getting an image upload to change the background of a table automatically. It works fine on Desktop computers, but not on IOS or Android. Does anyone have any advice on how to make it work across all devices? Thanks in advance. cons ...

loading times of Bootstrap-select are slow when used in multiples

I am facing performance issues on my website when I try to include more than 20 select options. The jQuery execution slows down significantly and there is a stop/continue alert, taking minutes to load. Is there any way to optimize the code for faster loadi ...

What is the best way to transfer a request parameter from a URL to a function that generates an object with matching name in JavaScript?

I need to figure out how to pass a request parameter from an express router request to a function that should return an object with the same name. The issue I'm facing is that the function is returning the parameter name instead of the object. Upon c ...

Function modifies global variable

What could be causing the global variable to change when using the function write_ACK_ONLY()? I'm passing the array rxUartBuffer to write_ACK_ONLY() as data = new Array(20), but upon checking the Log Output, it seems that the function is also modifyin ...

Utilize a JavaScript function on an element that is generated dynamically

I am encountering an issue with my autocomplete function. It works perfectly fine for the input field with the id "field10" that is already created. However, when I dynamically generate new input fields, the function does not seem to work on them. I have ...

selectize.js typescript: Unable to access values of an undefined object (reading '0')

I've been working on incorporating selectize.js into my project using webpack and typescript. After installing selectize.js and the necessary types, I added the following to my code: yarn add @selectize/selectize yarn add @types/select2 Within my c ...

What are the implications of sending a query for every individual input field alteration in a large online form?

I am creating a system for an educational institution where faculty can input scores using php and html. The layout is similar to an excel sheet, with 20 questions per student and about 60 students on each page. My dilemma is whether it's acceptable ...

What is the reason for the lack of functionality of the "unique" field when creating a schema?

I've created a schema where the username field should be unique, but I'm having trouble getting it to work (The "required" constraint is functioning correctly). I've tried restarting MongoDB and dropping the database. Any idea what I might b ...

Troubleshooting Problem with CSS Display in Spring Security 3.2

After deciding to integrate 'Spring security 3.2.0' into my current web application, which was originally developed without Spring and utilizes Primefaces & EJB 3, I encountered a challenge. Upon starting the basic configurations, I noticed that ...

What is the trick to shortening paragraphs with dots...?

There is a p tag, <p> most iconic character in cinema</p> I need to truncate the text after 8 characters, and display dots afterwards. For example: most ic... Is there a way to achieve this using CSS? Any help with AngularJS would also be ...

What is the best way to send a prop to my home route following a redirect?

I am working with react-router-dom and I want to pass :id to my first route (/) when redirecting. This is important so that I can access :id in my Interface component and maintain consistent URL structure for my single-page application. Is it feasible to a ...

Troubleshooting: CSS Pseudo :after doesn't apply to an anchor tag

I've created a pseudo CSS style for an anchor tag, which was working fine before. However, for some reason, it's no longer working. I tried using Chrome inspect element to add the CSS but it's not being read by the anchor tag. @font-face ...

Tips for managing the transparency level of a container's backdrop using CSS?

Is there a way to adjust the transparency of an image, change the background color of a container, button, or form using CSS? Which specific property would be appropriate for this task? ...

What is the method for accessing the constructor type of an interface?

I am familiar with accessing a property type of an interface using interfaceName['propertyName'], but how can we access the constructor? For example: interface PromiseConstructor { new <T>(executor: (resolve: (value?: T | PromiseLike& ...

AngularJS: Validators in Controller do not directly bind with HTML elements

The in-line validations on the HTML side are functioning properly, but when I utilize functions in my Controller (specifically ingresarNuevoEmpleador and limpiarNuevoEmpleador), the $invalid value is always true. Additionally, $setPristine does not seem to ...

The landscape orientation media query does not adhere to the specified maximum width

I am currently working on creating a mobile landscape design for a website specifically tailored for iPhone SE and iPhone 12. In the process, I encountered an issue that caught my attention: Within two different breakpoints, I made adjustments to the top ...

Interactions between a service and a directive: interdependence or triggering of events

Issue: managing multiple directives that interact with a service or factory to communicate and log actions with a server. Should I establish dependencies between them? angular.module('someModule', []) .directive('someDir', ['l ...