FussinHussin
FussinHussin

Reputation: 1814

Template parse errors: Can't bind to DIRECTIVE since it isn't a known property of 'div'

I have looked at the questions regarding this error, and have not found a solution.

I have a highlight directive, and I take an input index. This directive works when I declare it in the module I'm using it in. But I want to use it in several modules, So I removed the declaration, and put it inside of my root module that imports the errors. That is when I get the error:

 Error: Template parse errors:
Can't bind to 'index' since it isn't a known property of 'div'. ("
                <div class="read row"
                    appListHighlight
                    [ERROR ->][index]="index"
                >
                    <div class="col"></div>
"): ng:///NetworkModule/DnsComponent.html@15:20

My directive:

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

@Directive({
    selector: '[appListHighlight]'
})
export class ListHighlightDirective implements OnInit{
    @HostBinding('style.backgroundColor') backgroundColor = 'transparent';

    @Input() index: string;

    constructor() {}

    ngOnInit() {

        console.log('APP', this.index);

        if (+this.index % 2 === 0) {
            this.backgroundColor = 'rgba(128, 128, 128, 0.08)'
        }
    }
}

my html:

<div class="read row"
                    appListHighlight
                    [index]="index"
>

the html is part of a component inside my network module, which is imported into my root module like so

import { ListHighlightDirective } from './shared/list-highlight.directive';
import { NetworkModule } from './network/network.module';

declarations: [
    AppComponent,
    ListHighlightDirective
],

So what is happening? why does this work when the directive is imported to my networkModule, but not my root module? doesn't the root module compile everything in the app that it imports so all the imports are included?

--------------------______UPDATE_____------------------------

I created a shared module, and imported it, but i'm getting the same error. my module looks like this:

import { ListHighlightDirective } from './list-highlight.directive';
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';

@NgModule({
    declarations: [
        ListHighlightDirective
    ],
    imports: [
        CommonModule
    ]
})

export class SharedModule { }

Upvotes: 6

Views: 16340

Answers (3)

ImFarhad
ImFarhad

Reputation: 3209

To use a Module's components or directives in other modules, you need to define it in two places of a @NgModule decorator, declarations and exports.
In your SharedModule, you are not declaring it in exports array. add exports array like his

import { ListHighlightDirective } from './list-highlight.directive';
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';

@NgModule({
    declarations: [
        ListHighlightDirective
    ],
    imports: [
        CommonModule
    ],
    exports: [
      ListHighlightDirective
    ]

})

export class SharedModule { }

Now Wherever you will import the SharedModule, you will be able to use it's exported members (components/directives).
For this example, you can use ListHighlightDirective.

Upvotes: 1

Z. Bagley
Z. Bagley

Reputation: 9270

The error you're receiving is because the component is out of scope of the import location. The reason it works in your submodule would be because the component is declared in that submodule. The reason it doesn't work in other modules is because the component or directive aren't declared in the module.

Why?

At run time Angular will look at each module in a case by case basis. If the directive is declared in a sub-module it will check against components declared in that module and use the directive for them. If the directive is declared in your app.module it will only check against components directly declared in your app.module.

Solution?

The general solution is that you should declare a directive in each module where you declare a component that uses it. The other option is to add the directive into a shared module, and use the shared module in every other module where a component uses the directive.

Upvotes: 2

DeborahK
DeborahK

Reputation: 60538

An Angular module defines the template resolution environment for the template associated with every declared component. That means that when a component's template is parsed, it looks to THAT component's Angular module to find all of the referenced components, directives, and pipes.

A more common practice for something like this is to add the appListHighlight to a Shared module and then import that Shared module into your network module.

I have a youtube video about these concepts here: https://www.youtube.com/watch?v=ntJ-P-Cvo7o&t=6s

Or you can read more about this here: https://angular.io/guide/ngmodule-faq

In the picture below, I do something similar with the StarComponent, which is a nested component that turns a number into rating stars. You can use this same technique for your directive.

enter image description here

Upvotes: 13

Related Questions