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

查看:22
本文介绍了不能在 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天全站免登陆