Extending Directives in Angular 4

skepticscript picture skepticscript · Oct 30, 2017 · Viewed 7.1k times · Source

I'm trying to extend NgbPopover in order to dispatch a custom action when the popover's open or close methods are called.

I have the following set up:

custom-popover.directive.ts

@Directive({  
    selector:'[customPopover]',
    exportAs:'customPopover'
}) 
export class CustomPopover extends NgbPopover {}

some-list.component.ts

<input #quantityInput
       (input)="onInputChange()"
       type="number"

       popoverTitle="Warning!"
       [customPopover]="validationError"
       #validationPopovers="customPopover">

<ng-template #validationError>{{ message }}</ng-template>

I expect this to behave like the original NgbPopover(allowing me to override the open and close methods if I so wish), but instead I get the following error:

Can't bind to 'customPopover' since it isn't a known property of 'input'.

EDIT (to show declarations/imports in modules):

custom-popover.module.ts

@NgModule({
    declarations: [
        CustomPopover
    ],
    imports: [
        NgbModule
    ],
    exports:[CustomPopover]
})
export class CustomPopoverModule { }

app.module.ts

@NgModule({
    imports: [
       ...
       CustomPopoverModule
    ],
    ...
})

some-list.module.ts

@NgModule({
    imports: [
        ...
        NgbModule,
        CustomPopoverModule
    ],
    ...
})

Answer

skepticscript picture skepticscript · Nov 1, 2017

Okay I found the issue. In addition to supplying selector and exportAs properties, one also needs to add an Input() string that corresponds with the selector in order to apply [customPopover] to an element, so the directive becomes:

@Directive({  
    selector:'[customPopover]',
    exportAs:'customPopover'
}) 
export class CustomPopover extends NgbPopover {
    @Input()
    customPopover: string;
}