передача параметров в угловую директиву - PullRequest
0 голосов
/ 03 декабря 2018

У меня были котята о количестве глобальных обнаружений угловых изменений каждый раз, когда происходило событие, и я обнаружил, что Angular 2 runOutsideAngular все еще меняет пользовательский интерфейс , и я принял стратегию OutSideEventHandlerDirective.

Однако теперь у меня есть файл с 6 директивами, каждая для своего типа события.

Что я хотел бы сделать, это передать тип события в директиву;т.е. установите @Input () event: string = 'my type type' внутри директивы из шаблона html.

Возможно ли это вообще?

Итак, спасибо за ответыдалеко.Добавлено в качестве редактирования, чтобы иметь более приятное представление, чем комментарий:

Что нужно изучить:

1 / @input () xyz: string = 'hello' - вы можете установить этот вводв шаблоне с помощью (outSideEventHandler) = "onEv ($ event)" [xyz] = "до свидания"

2 / @input ('abc') xyz: string = 'hello' - 'переименовывает' вещьвы используете для ссылки на вход, то есть теперь вы используете [abc] = "до свидания"

Дополнение к вопросу:

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 голосов
/ 04 декабря 2018
Directive({
    selector: '[testDirective]'
})
export class TestDirective implements OnInit {

    @Input() testDirective: string;

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

шаблон

<button [testDirective]="<event-name>" // this will add the directive and also set the input
        [otherInput]="<other-input>"> // other input
</button>
0 голосов
/ 04 декабря 2018

Вы можете добавить дополнительные параметры, используя псевдонимы с декоратором @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, который его реализует.Он выводит тип в журнал консоли, чтобы можно было применить его.

Здесь также есть решение для регистрации нескольких обработчиков событий, чтобы ответить и на ваше добавление.Я думаю, что для этого лучше всего иметь входной параметр по умолчанию и отправлять массив пар имени события и обработчика в директиву.Например, вы можете создать объект 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, реализующий этот подход.

...