Utilizing NgClass Within an Attribute Directive in Angular 2.4.0

Is there a way to utilize NgClass within a custom attribute directive to modify the CSS class of the main elements?

For example, if I have this code snippet:

@Component({
  selector: 'my-app',
  template: `
    <div>
      <div class="box" myDir [ngClass]="{'blue': blue, 'red': red}">   </div>
    </div>
  `,
});

And then, within the myDir directive, something like this:

import { Directive, HostListener, OnInit } from '@angular/core';

@Directive({
  selector: '[myDir]'
})

export class MyDirDirective {
  blue: boolean;
  red: boolean;

  constructor() { 
  }

  ngOnInit() {
  } 

  @HostListener('mouseenter', ['$event'])
  onMouseEnter(event) {
    event.preventDefault();
    event.stopPropagation();

    this.blue = true;
    this.red = false;

    console.log('mouseenter');
  }

  @HostListener('mouseleave', ['$event'])
  onMouseLeave(event) {
    event.preventDefault();
    event.stopPropagation();

    this.blue = true;
    this.red = false;

    console.log('mouseleave');
  }

Do I have access to the scope where blue and red are located? While I can update these values with a button toggle, it seems like modifying them within the directive itself is not straightforward. Is this the correct approach or is there another solution that is not covered in the documentation?

Answer №1

The blue\red properties within your scenario are located within the parent component scope named my-app.

To modify the value, you can create an Output event inside your directive that can be subscribed to in the parent component.

Here is an example:

@Directive({
  selector: '[myDir]'
})
export class MyDirDirective {
  blue: boolean;
  red: boolean;

  @Output() myEvent = new EventEmitter();

  @HostListener('mouseenter', ['$event'])
  onMouseEnter(event) {
    event.preventDefault();
    event.stopPropagation();
    this.myEvent.next('blue');
  }

  @HostListener('mouseleave', ['$event'])
  onMouseLeave(event) {
    event.preventDefault();
    event.stopPropagation();
    this.myEvent.next('red');
  }
}

Then, subscribe to this event in the parent component to update the color to blue\red.

@Component({
  selector: 'my-app',
  template: `<h1>Hello {{name}}</h1>
  <div class="box" myDir (myEvent)="myEvent($event)"
        [ngClass]="{'blue': color === 'blue', 'red': color === 'red'}"> Hello World!!</div>
  `,
  styles:[`
  .blue{
    border: 1px solid blue;
  }
  .red{
     border: 1px solid red;
  }`]
})
export class AppComponent { 
  name = 'Angular';
  color = 'blue';

  myEvent(val){
    this.color = val;
  }
}

Feel free to take a look at this Plunker!

I hope this explanation helps! If you have any questions, please let me know.

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 NG8002 error has occurred, as it is not possible to connect to 'matDatepicker' because it is not a recognized attribute of 'input'

I've come across an issue while working on my Angular 15 application with Angular Material. I'm trying to incorporate a date picker, but after adding the code snippet below, I encountered an error. <mat-form-field appearance="outline" ...

Can a type be established that references a type parameter from a different line?

Exploring the Promise type with an illustration: interface Promise<T> { then<TResult1 = T, TResult2 = never>( onfulfilled?: | ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ...

Using renderProps in combination with TypeScript

I've encountered an issue while trying to convert my React project to TypeScript, specifically with the login component that uses react-google-login. The error I'm facing is related to renderProps: Overload 1 of 2, '(props: { component: El ...

Angular component linked to a dynamic object requiring user confirmation before changing or reverting to the original value

I've been working on getting a simple <select> behavior where the value reverts back if the user cancels the change. I managed to achieve it, but it took me quite a few hours and I'm not entirely satisfied with the implementation as it&apos ...

Can one extract request data from an rxjs-timeout-error?

Currently, I am working on enhancing our error handling system, particularly in providing better descriptions of errors in both general and testing environments. My focus is on an Ionic app, but I am facing challenges with the rxjs timeout method. One asp ...

What is the best way to retrieve the value of this object?

In my project, I am utilizing Angular 8 to extract data from a radio input. However, when I transmit this data to Node.js and then to a MongoDB database, it is not being properly registered. The entry in the database collection appears as follows: "__v" : ...

Using {angular} import from 'angular' is causing a malfunction in AngularJS version 1.5

React - 17.0 TypeScript - 4.1.2 Babel - 7.13.14 tsconfig.json { "compilerOptions": { "target": "es6", "module": "esnext", "moduleResolution": "node", "jsx": ...

Any ideas for handling ProtractorJS timeouts while clicking an element?

The Issue at Hand I am currently facing a challenge with clicking a straightforward 'New Booking' button in my Angular 5 Material 2 Application. The code snippet for the button is as follows: <button _ngcontent-c9="" class="mat-menu-item" ma ...

One efficient way to iterate through an object and modify its values in a single line of code

_shop: { [key: string]: string[] } = { fruits: ['Apple', 'Orange'], vegetables: ['Tomato', 'Onions'] } Can a one-liner code be used to modify the values of _shop and return it in a specific format? The desired outp ...

Can the variable name within a function be retrieved?

How can I retrieve the variable name (user_name1 or user_name2) from a sample function (GetUserName()) within itself? This variable name is required to create an object with the same name on the server side for data synchronization purposes. function GetU ...

What is the best way to interact with the member variables and methods within the VideoJs function in an Angular 2 project

Having an issue with accessing values and methods in the videojs plugin within my Angular project. When the component initializes, the values are showing as undefined. I've tried calling the videojs method in ngAfterViewInit as well, but still not get ...

What sets apart the two methods of defining an event in a React component?

Can you explain the nuances between these two approaches to declaring events in a React component? Is it merely a matter of personal preference, or are there more subtle distinctions between them? interface PropsX { onClick: () => void; } const But ...

Combining array elements into functions with RxJS observables

I am facing a scenario where I have an array of values that need to be processed sequentially using observables in RxJS. Is there a more optimized way to achieve this instead of using nested subscriptions? let num = 0; let myObs = new Observable(obs ...

Angular 2+ Service for tracking application modifications and sending them to the server

Currently I am facing a challenge in my Angular 4 project regarding the implementation of the following functionality. The Process: Users interact with the application and it undergoes changes These modifications are stored locally using loca ...

What steps can be taken to establish an array type that is limited to predefined values?

I am currently working on defining a type for an array that requires specific values to be present in a certain order at the beginning of the array. type SpecificArray = ('hello'|'goodbye'|string)[] // Current const myArray: SpecificAr ...

Creating a dynamic navigation bar that adjusts to changing content requires careful planning and implementation

Struggling with achieving my visual mockup while designing a webpage: Check out my web design mockup Currently focusing on section 2 of the page. Using Angular 5, Bootstrap 3, and ngx-bootstrap library to integrate Bootstrap components into Angular. Here ...

Error in React: Trying to access property 'functionName' of an undefined object on click event

I am facing an issue while trying to click a button in my React component that is supposed to trigger a function with a parameter named "item" which is defined within the function. The pseudo-HTML snippet for this scenario looks like: <div>{item.cre ...

NestJS's "Exclude" decorator in class-transformer does not exclude the property as expected

I attempted to exclude a specific property within an entity in NestJS, but it appears that the exclusion is not working as expected. When I make a request, the property is still being included. Code: // src/tasks/task.entity.ts import { Exclude } from &ap ...

A guide on transitioning from using require imports to implementing ES6 imports with the concept of currying

Currently in the process of migrating a Node/Express server to TypeScript. I have been using currying to minimize import statements, but now want to switch to ES6 import syntax. How can I translate these imports to ES6? const app = require("express")(); ...

Typescript PDFjs encountering loading issues with corrupt files

In my Vue.js application, I have the following TypeScript class: /** Taken from https://github.com/VadimDez/ng2-pdf-viewer/blob/master/src/app/pdf-viewer/pdf-viewer.component.ts */ import { Component, Vue } from 'vue-property-decorator'; import ...