프로필사진
[Angular] directive selector를 Input/Output alias로 사용하기 (custom directive)

2020. 10. 7. 18:31🔴 Angular

300x250

Angular 에서는 3종류의 directive가 있다 :

1. Componenets - template을 지니고 있는 directive (가장 흔함)
2. Structural directives - DOM 엘리먼트를 추가하거나 지우면서 DOM의 레이아웃을 바꿈 (ex. NgFor, NgIf)
3. Attribute directives - 엘리먼트, 컴포넌트, 다른 directive의 형태나 동작을 바꿈 (엘리먼트의 attribute로 사용됨)

 


우리는 attribute directive를 만들어 해당 directive selector로 Input/Output 이벤트를 바인딩 시킬 것이다.

CLI Command :

ng generate directive custom-enter
import { Directive } from '@angular/core';

@Directive({
  selector: '[custom-enter]'
})
export class CustomEnterDirective {
  constructor() { }
}

'@Directive' 어노테이션이 붙은 directive가 만들어졌다.
그 안에 'selector'에서 directive의 이름을 원하는대로 바꿀 수 있다.

View :

<p custom-enter>Highlight me!</p>

이렇게 html에서 해당 directive를 사용할 수 있다.

ts 파일안의 코드를 조금 변경해 보았다 :

<CustomEnterDirective.directive.ts> :

import { Directive } from '@angular/core';

@Directive({
  selector: '[custom-enter]'
})
export class CustomEnterDirective {

  @Output('enter') enterEvent = new EventEmitter();
  
  constructor(private renderer: Renderer2, private element: ElementRef) {
  }
  
  ngOnInit() {
    this.renderer.listen(this.element.nativeElement, 'keyup', (event: KeyboardEvent) => {
      event.stopPropagation();
      if ('Enter' === event.key) {
        this.customEvent.emit(event);
      }
    });
  }
  
}

사용자가 Enter 키를 누르면 'enterEvent'로 되어있는 @Output 이벤트가 emit 된다.

View :

<p custom-enter (enter)="pressEnter($event)">Highlight me!</p>

이렇게 뷰단에서 'enter' 아웃풋을 받아서 원하는 함수를 실행시킬 수 있게 되었다.


여기서 우리는 attribute directive를 @Output()에 바인딩 시킬 수도 있다 (=Output alias)

<CustomEnterDirective.directive.ts> :

@Directive({
  selector: '[custom-enter]'
})
@Output('custom-enter') enterEvent = new EventEmitter();

directive selector의 이름과 @Output()의 이름을 동일하게 지정하면 된다.

View :

<p (custom-enter)="pressEnter($event)">Highlight me!</p>

이렇게 해서 해당 directive를 더 간단하게 사용할 수 있다.
만약 이름이 달랐다면 위의 예시처럼 'custom-enter'라는 directive 이름을 써야지
'(enter)="..."' 해당 directive의 Output을 받을 수 있다.

+

@Input 역시 동일하게 directive selector 이름 = @Input 이름으로 
directive를 이벤트 바인딩하는 목적으로 사용할 수 있다 :

@Directive({
  selector: '[appHighlight]'
})
export class HighlightDirective {

  @Input('appHighlight') highlightColor: string;

  constructor(private el: ElementRef) { }
}
<p [appHighlight]="color">Highlight me!</p>

참고 자료 :

angular.io/guide/attribute-directives

www.bennadel.com/blog/3024-selectors-and-outputs-can-have-the-same-name-in-angular-2-beta-6.htm?site-photo=712

300x250