Extend ng-boostrap popover component with custom angular directive

前端 未结 2 1330
终归单人心
终归单人心 2021-01-24 05:31

What i try to achieve is to extend ngbPopover directive and wrap in custom directive all this proeprties so instead of showing them just to include my directive.

For exa

相关标签:
2条回答
  • 2021-01-24 05:55

    Instead of creating a directive, you could also create a component with the selector my-popover.

    This component will hold your HTML template code:

    <button
        type="button"
        class="btn btn-primary mb-4"
        placement="right-top"
        [ngbPopover]="popOver"
        popoverClass="popover-custom"
        #popOverRef="ngbPopover"
        triggers="manual"
        [autoClose]="false"
        (click)="popOverRef.toggle()"
        (hidden)="onPopoverClose(options)"
    >
        Standard Picker
    </button>
    <ng-template #popOver>
        <popover [data]="options" [popover]="popOverRef"><popover>
    </ng-template>
    

    And then finally to use that, you could do the following:

    <my-popover></my-popover>
    

    If you need to interact with that component, e.g. to listen to the click events have a look at input and output bidings of components.

    Hope this helps!

    For more information on the difference between components and directives, you could check this question.

    0 讨论(0)
  • 2021-01-24 06:00

    Ok finally got this to work not sure why my previous code was not working. Anyway i succeed with extending ngbPopover directive. In my case i wanted popoup to be open on parent click for example button, this can be change to hover (mouseenter).... etc..

    import {
        ElementRef,
        Directive,
        Input,
        TemplateRef,
        EventEmitter,
        Renderer2,
        Injector,
        ComponentFactoryResolver,
        ViewContainerRef,
        NgZone,
        OnInit,
        OnDestroy,
        Inject,
        ChangeDetectorRef,
        ApplicationRef,
    } from '@angular/core';
    import { NgbPopover, NgbPopoverConfig } from '@ng-bootstrap/ng-bootstrap';
    import { DOCUMENT } from '@angular/common';
    
    @Directive({
        selector: '[customPopover]',
        exportAs: 'customPopover',
    })
    export class PopoverDirective extends NgbPopover implements OnInit {
        @Input() customPopover: TemplateRef<any>;
    
        constructor(
            private _elRef: ElementRef,
            private _render: Renderer2,
            injector: Injector,
            componentFactoryResolver: ComponentFactoryResolver,
            private viewContainerRef: ViewContainerRef,
            config: NgbPopoverConfig,
            ngZone: NgZone,
            private changeRef: ChangeDetectorRef,
            @Inject(DOCUMENT) _document: any,
            applicationRef: ApplicationRef
        ) {
            super(
                _elRef,
                _render,
                injector,
                componentFactoryResolver,
                viewContainerRef,
                config,
                ngZone,
                _document,
                changeRef,
                applicationRef
            );
            this.triggers = 'manual';
            this.popoverTitle = '';
            this.container = 'body';
            this.popoverClass = 'popover-custom';
            this.autoClose = false;
        }
    
        ngOnInit(): void {
            super.ngOnInit();
            this.ngbPopover = this.customPopover;
    
            // we need to listen on parent element click envet for example button
            // and toggle popover
            this._render.listen(this._elRef.nativeElement.parentNode, 'click', () => {
                this.toggle();
            });
        }
    
        ngOnDestroy(): void {
            super.ngOnDestroy();
        }
    }
    

    component that use this directive:

    <ng-template #popTemplate>
        <custom-content-comp [data]="test" [popover]="popOverRef"></custom-content-comp>
    </ng-template>
    <span [customPopover]="popTemplate" #popOverRef="customPopover" placement="right-top" triggers="manual">
        <ng-content></ng-content>
    </span>
    

    For popTemplate i am using again custom component this can be whatever we want either string either custom template.

    Usage:

    <div class="col-3">
                    <br />
                    <button
                        type="button"
                        class="btn btn-primary mb-4"
                        customPopoverComp
                        >
                        Standard Picker
                        </button>
                </div>
    
    0 讨论(0)
提交回复
热议问题