How do I pass a value from my Angular2 directive into the template?

My current setup includes a template named "starrating.component.html"

<ng-container *ngFor="let star of arrayStarts">
    <span class="glyphicon star" aria-hidden="true"
          [class.glyphicon-star-empty]="activeStar>=star? false : true"
          [class.glyphicon-star]="activeStar<star ? false : true"
          (click)="clickStar(star)"
          (mouseleave)="mouseleaveStar(star)"
          (mouseover)="mouseoverStar(star)" >
    </span>
</ng-container>

The corresponding component is "starrating.component.ts"

import { Component } from '@angular/core';
@Component({
    selector: 'star-rating',
    templateUrl: 'app/starrating/templates/starrating.component.html',
    styleUrls: ['app/starrating/css/style.css']
})

export class StarRatingComponent {
    public arrayStarts;
    public activeStar;
    public selectedStar;
    constructor() {
        this.arrayStarts = [1, 2, 3, 4, 5];
        this.activeStar = 0;
        this.selectedStar = -1;
    }
    mouseoverStar = function (star) {this.activeStar = star;}
    mouseleaveStar = function (star) {this.activeStar = this.selectedStar || 0;}
    clickStar = function (star) { this.selectedStar = star; }
}

The current functionality is satisfactory, but I am considering using Attribute directives for optimization. I made the following changes:

Updated template "starrating.component.html"

<ng-container *ngFor="let star of arrayStarts">
    <span class="glyphicon star" aria-hidden="true"
          [starHighlight]="star" 
          [class.glyphicon-star-empty]="activeStar>=star? false : true"
          [class.glyphicon-star]="activeStar<star ? false : true"
          >
    </span>
</ng-container>

Updated component "starrating.component.ts"

import { Component } from '@angular/core';
@Component({
    selector: 'star-rating',
    templateUrl: 'app/directives/starrating/templates/starrating.component.html',
    styleUrls: ['app/directives/starrating/css/style.css']
})
export class StarRatingComponent {
    public arrayStarts;
        this.arrayStarts = [1, 2, 3, 4, 5];
    }
}

Introducing the directive code in "starrating.directive.ts"

 import { Directive, ElementRef, Input, Output, Renderer, HostListener } from '@angular/core';

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

    export class StarHighlightDirective {

        constructor(private el: ElementRef, private  renderer: Renderer) { }

        private _selectedStar = -1;
        private _activedStar = 0;

        @Input('starHighlight') star: any;
        @Input('activeStar') activeStar: any;

        @HostListener('mouseenter') onMouseEnter() {this._activedStar = this.star;}
        @HostListener('click') onMouseCick() { console.log('onMouseCick: set star:', this.star);}
        @HostListener('mouseleave') onMouseLeave() { this._activedStar = this._selectedStar || 0;  }
 }

The events (click, mouseenter, and mouseleave) work perfectly within the directive.

To update the span element based on the "activeStar" variable, the following code should be used:

[class.glyphicon-star-empty]="activeStar>=star? false : true"

However, the value of "activeStar" is now defined within the directive, and passing values from the directive to the template proves challenging. Is there a more effective method to achieve this?

Answer №1

To assign a reference to a template variable and use it, you can specify the exportAs property as shown below:

@Directive({ selector: '[starHighlight]', exportAs: 'activeStar'})
<span class="glyphicon star" aria-hidden="true"
      #ref="activeStar"
      [starHighlight]="star" 
      [class.glyphicon-star-empty]="ref.activeStar >= star? false : true"
      [class.glyphicon-star]="ref.activeStar < star ? false : true"
      >
</span>

Please note that this code has not been tested yet.

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

Could a template variable be established for the p-dropdown element in template-driven form validation?

In the template, I have a p-dropdown element <p-dropdown id="output-method" [options]="outputMethods" [(ngModel)]="transformer!.outputMethod" pTooltip="Output Method" tooltipPosition="bottom&quo ...

Issues arising when routing ffmpeg to flac encoder

I am facing an issue with encoding a flac file with seektables. The ffmpeg's flac encoder does not include seektables, so I have to resort to using the flac Command Line Interface (CLI). My goal is to convert any arbitrary audio file into a seekable f ...

Struggling with module dependencies in Nest.js

I have been diving into the documentation provided on the NestJs website, but I've noticed that it can be a bit scattered. My goal is to retrieve an RPG Character from a Mongo database using TypeORM. Unfortunately, I seem to be running into dependency ...

Creating TypeScript declaration file for exporting JavaScript function

I'm a beginner with TypeScript and I want to learn how to create a declaration file for a custom JavaScript function. I attempted to do this, however, I encountered an error stating "Could not find a declaration file for module './main'." Ad ...

Condition not applying in the Modal

I implemented *ngif on a button to show/hide it based on a condition, but it's not working as expected. The button should appear when an item is selected from ng-select. Here is the button code: <button *ngIf="switch" (click)="productSaveInCart() ...

transferring data from service to component

Dealing with the challenge of passing a variable from a service (LibraryService) to a component located one level deeper in the directory structure (ReadingPaneComponent) has been quite troublesome for me. This predicament arose after successfully transfer ...

SweetAlert2 not displaying properly in Ionic6 - troubleshooting the issue

My current project is an Ionic 5 Angular project with SweetAlerts2 popups. Recently, I decided to upgrade to Ionic6 and encountered an issue where the SweetAlerts2 popups are not displaying correctly. The alert seems to only show up in the header, leaving ...

Toggle visibility of layers in ngx-mapboxgl

As I delve into ngx-mapboxgl, it becomes apparent that the documentation is lacking. My goal is to construct a layer with markers that can be toggled on and off. Despite following an example from the web, I encounter a runtime error claiming it cannot loca ...

Angular 2 Release Candidate 6 form input pattern always fails to pass

How can I ensure that a required input in my form fails validation if there is no non-whitespace character present? Despite setting the pattern to [/S]+, the validation does not pass. Could I be missing an import or something else? My Template: <form ...

Step-by-step guide on displaying SVG text on a DOM element using Angular 8

I have a FusionChart graph that I need to extract the image from and display it on the same HTML page when the user clicks on the "Get SVG String" button. I am able to retrieve the SVG text using this.chart.getSVGString() method, but I'm unsure of ho ...

Utilizing indexes to incorporate elements into an object array

I'm currently working on a project using Angular. I have an index coming from the HTML, and here is the code snippet: save(index){ //this method will be called on click of save button } In my component, I have an array structured like this: data = [{ ...

The NgFor is unable to iterate over an array because it is being treated as an

When attempting to call a new endpoint for displaying data, I noticed that the previous set of data is wrapped with an extra pair of brackets '[]', which seems to be causing a problem. The new endpoint does not format the data in this way when I ...

The data type 'string[]' cannot be assigned to the data type 'listData[]'

I'm currently developing a flexible component that allows the list view to be utilized by different components. However, the challenge arises from the fact that each component has a different data format. In my project, I'm unable to use type any ...

Avoid flickering of images by properly handling the object URL when setting the image source in an asynchronous pipe

Implementing a JWT authorized endpoint for images has made it impossible to directly link to image urls in HTML. To work around this issue, we have created an async pipe that loads the image with proper authorization (handled by an HTTP interceptor, not s ...

Submitting forms using Ajax in Angular 2

As a novice in Angular 2, with some experience in AngularJS, I am looking for guidance on how to utilize $.ajaxSubmit() or a similar method to submit a form using AJAX instead of the default form submission. Specifically, I am interested in uploading files ...

Determining the return type of a function by analyzing its argument(s)

I'm interested in defining a method within a class that will have its type based on the argument provided in the constructor. For example: class A { private model: any; constructor(model: any) { this.model = model; } getModel( ...

Angular 2 testing error: Unable to connect to 'ngModel' as it is not recognized as a valid property of 'input'

Currently, I am experimenting with angular2 two-way binding for the control input. Below is the issue that I encountered: An error occurred: Can't bind to 'ngModel' since it isn't a known property of 'input'. Contents of app. ...

Matching TypeScript values and types does not function as intended

Recently, I delved into TypeScript to work on my new AngularJS project. However, I encountered an issue where the id, which is supposed to be of type number, is actually being treated as a string. Have I overlooked something in my code? interface IRout ...

Typescript is throwing an error stating that the type 'Promise<void>' cannot be assigned to the type 'void | Destructor'

The text editor is displaying the following message: Error: Type 'Promise' is not compatible with type 'void | Destructor'. This error occurs when calling checkUserLoggedIn() within the useEffect hook. To resolve this, I tried defin ...

Developing a React-based UI library that combines both client-side and server-side components: A step-by-step

I'm working on developing a library that will export both server components and client components. The goal is to have it compatible with the Next.js app router, but I've run into a problem. It seems like when I build the library, the client comp ...