将参数传递给角度指令

时间:2018-12-03 18:09:47

标签: angular angular6 angular-directive

每当事件发生时,我都会发现有关全局Angular变化检测数量的小猫,我发现 Angular 2 runOutsideAngular still change the UI 我采用了“ OutSideEventHandlerDirective”策略。

但是,现在我有一个文件,其中包含6个指令,每个指令用于不同的事件类型。

我想做的是将事件类型传递给指令;即设置 @Input()事件:字符串='我的事件类型' 在模板html的指令中。

这有可能吗?

因此,谢谢您到目前为止的回答。 作为修改添加,使演示文稿比注释更好:

要学习的东西:

1 / @input()xyz:字符串='hello'-  您可以使用(outSideEventHandler)=“ onEv($ event)” [xyz] =“ goodbye”

在模板中设置此输入

2 / @ input('abc')xyz:字符串='hello'-  “重命名”您用来引用输入的内容,即现在您使用[abc] =“ goodbye”

问题的补充:

3 /我在同一元素上使用了两个或多个这些“外部”指令。  如果您有(outSideEventHandler)=“ onEvent1($ event)” [event] =“ mousedown”(outSideEventHandler)=“ onEvent2($ event)” [event] =“ mouseup”-那么您将获得该指令的两个副本,但是都使用event = mousedown。

我可以创建该指令的两个(或更多)副本(请参见code),然后为每个副本分别具有唯一的命名输入。但这是唯一的方法吗?

  (outSideEventHandler1)="onTestDirective($event)" 
  [outSideEvent1]="'mousedown'" 
  (outSideEventHandler2)="onTestDirective($event)" 
  [outSideEvent2]="'mouseup'" 

2 个答案:

答案 0 :(得分:2)

您可以通过在@Input装饰器中使用别名来添加其他参数。

这里是一个示例,您可以使用其他参数从链接的帖子中扩展指令。

import { NgZone, ElementRef, EventEmitter, Input, Output, Directive } from '@angular/core'

@Directive({
  selector: '[outSideEventHandler]'
})
export class OutSideEventHandlerDirective {
  private handler: Function;

  @Input() event: string = 'click'; // pass desired event
  @Output('outSideEventHandler') emitter = new EventEmitter();
  @Input('outSideEventType') type = 'default type';

  constructor(private ngZone: NgZone, private elRef: ElementRef) {}

  ngOnInit() {
    console.log(this.type);
    this.ngZone.runOutsideAngular(() => {
      this.handler = $event => this.emitter.emit($event);
      this.elRef.nativeElement.addEventListener(this.event, this.handler);
    });
  }

  ngOnDestory() {
    this.elRef.nativeElement.removeEventListener(this.event, this.handler);
  }
}

您可以通过以下方式使用它:

<button (outSideEventHandler)="onTestDirective()" [outSideEventType]="'My type'">Test Directive</button>

这里也是实现它的StackBlitz示例的link。它将类型输出到控制台日志中,以便您可以应用它。

这里还是多个事件处理程序注册的解决方案,也可以回答您的添加问题。 为此,我认为最好的解决方案是仅具有默认输入参数,并将事件名称和处理程序对的数组发送到指令。例如,您可以创建一个对象EventHandler:

export class EventHandler {
  public event: string;
  public handler: EventListener;
}

然后将指令更改为仅接受一个默认输入,该默认输入是EventHandler对象的数组。

import { NgZone, ElementRef, EventEmitter, Input, Output, Directive } from '@angular/core';
import { EventHandler } from './event-handler';

@Directive({
  selector: '[outSideEventHandlers]'
})
export class OutSideEventHandlerDirective {
  @Input() public outSideEventHandlers: EventHandler[];


  constructor(private ngZone: NgZone, private elRef: ElementRef) {}

  ngOnInit() {
    this.ngZone.runOutsideAngular(() => {
      for (let eventHandler of this.outSideEventHandlers) {
        console.log(eventHandler.event);
        this.elRef.nativeElement.addEventListener(eventHandler.event, eventHandler.handler);
      }

    });
  }

  ngOnDestory() {
    for (let eventHandler of this.outSideEventHandlers) {
        this.elRef.nativeElement.removeEventListener(eventHandler.event, eventHandler.handler);
      }
  }
}

然后您以这种方式在模板中使用它:

<button [outSideEventHandlers]="[{ event: 'click', handler: onClick }, { event: 'mousedown', handler: onMouseDown }, { event: 'mouseup', handler: onMouseUp}]">Test Directive</button>

这样,您可以在同一元素上添加任意数量的处理程序,而在指令上没有任何其他属性。这是实现此方法的StackBlitz示例的link

答案 1 :(得分:0)

getAllKeys

模板

Directive({
    selector: '[testDirective]'
})
export class TestDirective implements OnInit {

    @Input() testDirective: string;

    @Input() otherInput: string = 'Saving'; // if you need more than one input
}