Ben Cameron
Ben Cameron

Reputation: 4443

Angular 2 directive change detection, directive not updating

I have an Angular 2 app that displays a number. The number can be negative or positive. If the value is negative I am setting the font color to red. I am doing this via a directive. This number is constantly updated via an emitter.

The problem I am having is when the value changes from a negative to positive value. The directive isn't picking up this change and is very slow to run, ie the color is not updating. I have to click anywhere on the screen and then the font color changes. I don't think change detection is happening when I need it to.

How do I make this directive update at the same time the underlying value does?

My directive looks like this...

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

@Directive({ selector: '[negativeValueStyle]' })
export class NegativeValueStyleDirective {

    constructor(private el: ElementRef) { }

    ngAfterContentChecked() {

        if (this.el.nativeElement.innerHTML < 0)
            this.el.nativeElement.style.color = 'red';
        else
            this.el.nativeElement.style.color = 'black';
    }
}

It is being applied to the UI like this...

<td negativeValueStyle>{{data.return | number: '1.2-2'}}%</td>

Upvotes: 1

Views: 2243

Answers (1)

Poul Kruijt
Poul Kruijt

Reputation: 71971

Oh dear, that looks like a wrong approach to use angular and it's capabilities. I believe a better approach would be to use the binding on style.color in combination with a value passed through the negativeValueStyle directive:

untested code ahead

@Directive({ selector: '[negativeValueStyle]' })
export class NegativeValueStyleDirective {

    @Input('negativeValueStyle')
    public value: number;

    @HostBinding('style.color')
    public get color(): string {
       return this.value < 0 ? 'red' : 'black';
    }

    @HostBinding('innerHtml')
    public get innerHtml(): string {
       return this.value + '%';
    }
}

you can then use this directive like this:

<td [negativeValueStyle]="data.return | number: '1.2-2'"></td>

Upvotes: 7

Related Questions