无法识别自定义指令

时间:2019-04-05 13:36:48

标签: angular

我创建了一个名为holdable的自定义指令。

import { Directive, EventEmitter, Output, HostListener,  } from '@angular/core';

import { Observable, Subject, interval } from 'rxjs';
import { takeUntil, tap, filter } from 'rxjs/operators';

@Directive({
  selector: '[appHoldable]'
})
export class HoldableDirective {

  @Output() holdTime: EventEmitter<number> = new EventEmitter();

  state: Subject<string> = new Subject();

  cancel: Observable<string>;

  constructor() { 
    this.cancel = this.state.pipe(
      filter(v => v === 'cancel'),
      tap(v => {
        console.log('Stopped holding.');
        this.holdTime.emit(0);
      }
      )
    );
  }

  @HostListener('mouseup', ['$event'])
  @HostListener('mouseleave', ['$event'])
  onExit(){
    this.state.next('cancel');
  }

  @HostListener('mousedown', ['$event'])
  onHold(){
    console.log('Started holding.');
    this.state.next('start');
    const n = 100;
    interval(n).pipe(
      takeUntil(this.cancel),
      tap(v => {
        this.holdTime.emit(v * n);
      })
    )
    .subscribe()
  }
}

它已在AppModule中注册,因为我想在总体应用程序中使用它。例如在我的名为CashRegisterModule的模块中:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { CashRegisterRoutingModule } from './cash-register-routing.module';

import { CashRegisterComponent } from './cash-register.component';
import { UIModule } from '../UI/ui.module';
import { ScannerComponent } from './steps/scanner/scanner.component';
import { ArticlePreviewComponent } from './steps/article-preview/article-preview.component';
import { OverviewComponent } from './steps/overview/overview.component';
import { PaymentComponent } from './steps/payment/payment.component';

@NgModule({
  declarations: [
    CashRegisterComponent, 
    ScannerComponent, 
    ArticlePreviewComponent, OverviewComponent, PaymentComponent
  ],
  imports: [
    CommonModule,
    CashRegisterRoutingModule,
    UIModule
  ]
})
export class CashRegisterModule { }

此模块也已注册在app.module.ts文件中,看起来像这样

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { HttpClientModule } from '@angular/common/http';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { LoginComponent } from './login/login.component';
import { DashboardModule } from './views/dashboard/dashboard.module';
import { UIModule } from './UI/ui.module';
import { ArticleModule } from './views/article/article.module';
import { ArticleService } from './services/article.service';
import { UiService } from './services/ui.service';
import { CashRegisterModule } from './cash-register/cash-register.module';
import { DataService } from './services/data.service';
import { HoldableDirective } from './directives/holdable.directive';

@NgModule({
  declarations: [
    AppComponent,
    LoginComponent,
    HoldableDirective,
  ],
  imports: [
    CommonModule,
    BrowserModule,
    HttpClientModule,
    RouterModule,
    ReactiveFormsModule,
    DashboardModule,
    UIModule,
    ArticleModule,
    CashRegisterModule,
    AppRoutingModule
  ],
  providers: [
    ArticleService,
    UiService,
    DataService
  ],
  bootstrap: [
    AppComponent
  ],

})
export class AppModule { }

我在CashRegisterComponent的PaymentComponent内部的按钮中使用指令

<button *ngFor="let moneyType of state.moneyToRender"
      appHoldable (holdTime)="calculateGivenMoney(moneyType, $event)"
      >{{moneyType.toFixed(2)}} €
    </button>

calculateGivenMoney(…)将被初始化

calculateGivenMoney(amount: number, /*operation: string,*/ holdTime: number): number {
    console.log('ich werde geklickt.' + holdTime)
    if(holdTime > 1000){
      this.state.givenMoney = this.state.givenMoney - amount;
    } else {
      this.state.givenMoney = this.state.givenMoney + amount;
    } return this.state.givenMoney;
}

但是所有印刷声明均无效...

有人知道我的代码中没有什么工作吗?

非常感谢您的帮助,祝您有愉快的一天!

2 个答案:

答案 0 :(得分:1)

您似乎在考虑providers在模块中的工作方式,这种“自顶向下”的方法可以使提供方的模块下游的任何模块都可以使用它。

要在单个模块中使用组件或指令,则需要在单个模块中导入或声明它们。我的喜好是为该指令或功能较小的组创建模块,导出可重用的片段,并将其导入所需的位置(有关示例,请参见Angular Material library)。

在您的示例中使用它:

@NgModule({
  declarations: [
    HoldableDirective,
  ],
  exports: [
    HoldableDirective,
  ],
  imports: [
    CommonModule,
    ...
  ]
})
export class HoldableModule { }


@NgModule({
  declarations: [
    CashRegisterComponent, 
    ScannerComponent, 
    ArticlePreviewComponent, OverviewComponent, PaymentComponent,

  ],
  imports: [
    CommonModule,
    CashRegisterRoutingModule,
    UIModule,
    HoldableModule, // <-- useing that common module here

  ]
})
export class CashRegisterModule { }

答案 1 :(得分:1)

要执行此操作,需要三个步骤。它适用于几乎所有Angular元素,例如组件,指令,管道等。

  1. 在特定模块中声明指令,例如:SharedModule
  2. 从该模块中导出指令,即SharedModule
  3. 将该模块导入要使用它的组件的父模块中。例如:SomeOtherModule

示例代码:

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


@NgModule({
    declarations: [
        SomeChildComponent
    ],
    imports: [
        ... other modules,
        SharedModule
    ]
})
export class SomeOtherModule

这样,该指令及其相应的选择器将对SomeOtherModule的所有成员可用。

  

注意:如果希望模块成员成为成员,则导出模块成员很重要   可从其他模块访问。可以将其视为针对   模块。