Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom Angular 2 directive not working

Error
Template parse errors:
Can't bind to 'time-delta' since it isn't a known property of 'p'.

Solution in documentation
I have to add the Directive to declarations array. I've done this already.

Now my architecture: I have three Modules:

  • AppModule (root)
  • TimeModule (should be a helper module later with some directives)
  • AuthModule (Login, Sign up components and so on)

The AppModule:

@NgModule({
    imports: [
        TimeModule,
        BrowserModule,
        FormsModule,
        AuthModule,
        routing,
    ],
    declarations: [
        AppComponent
    ],
    providers: [
        appRoutingProviders
    ],
    bootstrap: [AppComponent]
})

AuthModule:

@NgModule({
    imports: [
        BrowserModule,
        FormsModule,
        authRouting
    ],
    declarations: [
        AuthComponent,
        LoginComponent,
        SignupComponent,
        LogoutComponent
    ],
    providers: [
        AuthGuard,
        AuthService
    ],
    bootstrap: [ LoginComponent ]
})

TimeModule:

@NgModule({
    declarations: [
        ReadableDatePipe,
        TimeDeltaDirective
    ]
})

And now I am trying to use my TimeDeltaDirective in a view of LoginComponent. And I already tried to add the directive to the other declarations arrays as well, but this won't work either.

I am thankful for any support! Thanks

TimeDeltaDirective:

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

@Directive({ selector: '[time-delta]' })
export class TimeDeltaDirective {
    constructor(renderer: Renderer, el: ElementRef) {
        function getTimeDelta(date: Date) {
            var now = new Date();
            return (now.getTime() - date.getTime()) / 1000;
        }

        this.delta = getTimeDelta(new Date(this.date));
    }

    @Input('date') date: string;
    delta: number;
}

usage in LoginComponent (example):

@Component({
    selector: 'login',
    template: `
    <p date="2016-09-28 00:00:00" [time-delta]>{{delta}}</p>
  `
})
like image 784
CodeWarrior Avatar asked Sep 28 '16 20:09

CodeWarrior


People also ask

Can we create custom directive in angular?

Angular provides many built-in Attribute Directives like NgStyle, NgClass, etc. We can also create our own custom Attribute Directives for our desired functionality.

Is ngModel an attribute directive?

The ngModel directive, which implements two-way data binding, is an example of an attribute directive. ngModel modifies the behavior of an existing element by setting its display property and responding to the changing events.

What is attribute directive in Angular?

The attribute directive changes the appearance or behavior of a DOM element. These directives look like regular HTML attributes in templates. The ngModel directive which is used for two-way is an example of an attribute directive.


1 Answers

You need to export TimeDeltaDirective from your TimeModule and then import TimeModule in your AuthModule because your LoginComponent is decalred there, and that's where you want to use your directive. This way, TimeDeltaDirective will be available for use in LoginComponent, as well as in other declared components of AuthModule. So, it should be something like this:

AuthModule

@NgModule({
    imports: [
        BrowserModule,
        FormsModule,
        authRouting,
        TimeModule
    ],
    declarations: [
        AuthComponent,
        LoginComponent,
        SignupComponent,
        LogoutComponent
    ],
    providers: [
        AuthGuard,
        AuthService
    ],
    bootstrap: [ LoginComponent ]
})

TimeModule

@NgModule({
    declarations: [
        ReadableDatePipe,
        TimeDeltaDirective
    ],
    exports: [
        TimeDeltaDirective
    ]
})
like image 166
Stefan Svrkota Avatar answered Oct 01 '22 02:10

Stefan Svrkota