不能在Angular 6的子模块的app模块内部声明的指令使用 [英] can't use directive declared inside app module in child modules in Angular 6

查看:47
本文介绍了不能在Angular 6的子模块的app模块内部声明的指令使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Angular 6.

我通过扩展 NbgPopover 来声明了指令 StickyPopover ,并在app.module.tsdeclaration中添加了

I have declared a directive StickyPopover by extending NbgPopover and have added in declaration of app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { AuthLayoutComponent } from './layouts/auth-layout/auth-layout.component';
import {AdminLayoutComponent} from './layouts/admin-layout/admin-layout.component';
import {FormsModule} from '@angular/forms';
import {RouterModule} from '@angular/router';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {NgbModule} from '@ng-bootstrap/ng-bootstrap';
import {StickyPopoverDirective} from './sticky-popover.directive';


@NgModule({
  declarations: [
    AppComponent,
    AuthLayoutComponent,
    AdminLayoutComponent,
    StickyPopoverDirective           // custom created directive
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    FormsModule,
    HttpClientModule,
    RouterModule,
    NgbModule.forRoot(),
  ],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule { }

,指令的位置与 app.module.ts 文件的位置相同.

and the location of the directive is at the same level as that of app.module.ts file.

sticky-popover.directive.ts 的内容是

import {
  ElementRef,
  Directive, Input, TemplateRef,
  EventEmitter,
  Renderer2,
  Injector,
  ComponentFactoryResolver,
  ViewContainerRef,
  NgZone, OnInit, OnDestroy
} from '@angular/core';

import { NgbPopover, NgbPopoverConfig } from '@ng-bootstrap/ng-bootstrap';

@Directive({
  selector: '[appStickyPopover]',
  exportAs: 'stickyPopover'
})
export class StickyPopoverDirective extends NgbPopover implements OnInit, OnDestroy {
  @Input() stickyPopover: TemplateRef<any>;

  popoverTitle: string;

  placement: 'auto' | 'top' | 'bottom' | 'left' | 'right' | 'top-left' | 'top-right' | 'bottom-left' |
    'bottom-right' | 'left-top' | 'left-bottom' | 'right-top' | 'right-bottom' | ('auto' | 'top' | 'bottom' |
    'left' | 'right' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'left-top' | 'left-bottom' |
    'right-top' | 'right-bottom')[];

  triggers: string;

  container: string;

  shown: EventEmitter<{}>;

  hidden: EventEmitter<{}>;

  ngpPopover: TemplateRef<any>;

  canClosePopover: boolean;

  toggle(): void {
    super.toggle();
  }

  isOpen(): boolean {
    return super.isOpen();
  }



  constructor(
    private _elRef: ElementRef,
    private _render: Renderer2,
    injector: Injector,
    componentFactoryResolver: ComponentFactoryResolver,
    private viewContainerRef: ViewContainerRef,
    config: NgbPopoverConfig,
    ngZone: NgZone
  ) {
    super(_elRef, _render, injector, componentFactoryResolver, viewContainerRef, config, ngZone, document);
    this.triggers = 'manual';
    this.popoverTitle = 'Permissions';
    this.container = 'body';
  }

  ngOnInit(): void {
    super.ngOnInit();
    this.ngbPopover = this.stickyPopover;

    this._render.listen(this._elRef.nativeElement, 'mouseenter', () => {
      this.canClosePopover = true;
      this.open();
    });

    this._render.listen(this._elRef.nativeElement, 'mouseleave', (event: Event) => {
      setTimeout(() => { if (this.canClosePopover) { this.close(); } }, 100);

    });

    this._render.listen(this._elRef.nativeElement, 'click', () => {
      this.close();
    });
  }

  ngOnDestroy(): void {
    super.ngOnDestroy();
  }

  open() {
    super.open();
    const popover = window.document.querySelector('.popover');
    this._render.listen(popover, 'mouseover', () => {
      this.canClosePopover = false;
    });

    this._render.listen(popover, 'mouseout', () => {
      this.canClosePopover = true;
      setTimeout(() => { if (this.canClosePopover) { this.close(); } }, 0);
    });
  }

  close() {
    super.close();
  }

}

我有一个模块 SavedSearches ,该模块导入了AdminModule内部,并在 app.module.ts

I have a module SavedSearches which is imported inside of AdminModule which is further declared inside app.module.ts

当我在 SavedSearches 模块之类的模板中使用 StickyPopover 指令时,

When I use StickyPopover directive inside the template of SavedSearches module like

<i class="fa fa-plus-circle" aria-hidden="true" appStickyPopover [popoverTitle]="additional" [autoClose]="true" data-placement="right"></i>

它给出错误为

can't bind to 'popoverTitle' since it isn't a known property of i

当我将指令移动到 SavedSearches 模块中并将其包含在 saved-searches.module.ts declaration中时,它运行良好,没有任何错误.

When I move the directive inside the SavedSearches module and include it in the saved-searches.module.ts declaration, it works fine without any error.

但是我不能在其他模块中使用它,而在其他模块中使用它会给出

But Then I can't use it in another module and using it in other modules gives

StickyPopovoerDirective是2个模块的声明的一部分. 将其移至导入这两个模块的上部模块中.

StickyPopovoerDirective is a part of the declaration of 2 modules. Move it in the upper module which imports these two modules.

推荐答案

该指令仅对AppModule可见,如果要在其他模块中使用它,则可以创建SharedModule.然后将StickyPopoverDirective添加到声明和导出中.

That directive is visible only for AppModule, if you want to use it into another modules, you can create a SharedModule. Then add StickyPopoverDirective into the declarations and exports.

@NgModule({
  declarations: [StickyPopoverDirective],
  exports: [StickyPopoverDirective]    
})
export class SharedModule { }

此后,您可以将SharedModule导入另一个模块并在其中使用指令.

After this you can import SharedModule into another modules and use your directive there.

这篇关于不能在Angular 6的子模块的app模块内部声明的指令使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆