๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ’ป Frontend/Angular

[Angular] Custom Directive ๋งŒ๋“ค์–ด ์ ์šฉํ•˜๊ธฐ (Create & Adjust a Custom Directive)

by Fomagran ๐Ÿ’ป 2022. 6. 9.
728x90
๋ฐ˜์‘ํ˜•

์•ˆ๋…•ํ•˜์„ธ์š” Foma ์ž…๋‹ˆ๋‹ค!

 

์ €๋ฒˆ ๊ธ€์— Angular์— ์ด๋ฏธ ๊ตฌํ˜„๋œ Built-in ๋””๋ ‰ํ‹ฐ๋ธŒ์— ๋Œ€ํ•ด์„œ ์•Œ์•„ ๋ณด์•˜๋Š”๋ฐ์š”.

 

์ด๋ฒˆ ๊ธ€์€ ์ง์ ‘ ์ปค์Šคํ…€ํ•œ ๋””๋ ‰ํ‹ฐ๋ธŒ๋ฅผ ๋งŒ๋“ค๊ณ  ์ ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ ์•Œ์•„ ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

๋ฐ”๋กœ ์‹œ์ž‘ํ• ๊ฒŒ์š”~


Generate Directive

 

์•„๋ž˜์™€ ๊ฐ™์ด ๋””๋ ‰ํ‹ฐ๋ธŒ๋ฅผ ์ƒ์„ฑํ•ด ์ค๋‹ˆ๋‹ค.

 

์ €๋Š” mouse control์— ๋”ฐ๋ผ ์Šคํƒ€์ผ์ด ๋ฐ”๋€Œ๋Š” ๋””๋ ‰ํ‹ฐ๋ธŒ๋ฅผ ๋งŒ๋“ค๊ฑฐ๊ธฐ ๋–„๋ฌธ์— mouseControl์œผ๋กœ ์ด๋ฆ„ ์ง€์–ด์ฃผ๊ฒ ์Šต๋‹ˆ๋‹ค.

 

ng g d ๋””๋ ‰ํ‹ฐ๋ธŒ์ด๋ฆ„
//or
ng generate directive ๋””๋ ‰ํ‹ฐ๋ธŒ์ด๋ฆ„

 

directive.ts

 

์•„๋ž˜์™€ ๊ฐ™์ด Directive๊ฐ€ ์ƒ์„ฑ ๋ ๊ฑฐ์—์š”.

 

@Directive์— selector๋กœ app + ๋””๋ ‰ํ‹ฐ๋ธŒ์ด๋ฆ„์œผ๋กœ ๋งŒ๋“ค์–ด์ง€๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

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

@Directive({
  selector: '[appMouseControl]',
})

export class MouseControlDirective {
  constructor() {}
}

 

์ด์ œ ๋งˆ์šฐ์Šค ์ปจํŠธ๋กค์— ๋”ฐ๋ผ์„œ ์—˜๋ฆฌ๋จผํŠธ ์Šคํƒ€์ผ์ด ๋ฐ”๋€Œ๋Š” ๊ฑธ ์ž‘์„ฑํ•ด ๋ณผ๊ฒŒ์š”.

 

๋จผ์ € ๊ฐ’์„ ์—˜๋ฆฌ๋จผํŠธ๋กœ ๋ถ€ํ„ฐ ๊ฐ’์„ ์ „๋‹ฌ ๋ฐ›์„ @Input ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ๋งŒ๋“ค์–ด ์ค„๊ฒŒ์š”.

 

* @Input

 

ํ…œํ”Œ๋ฆฟ์˜ DOM ํ”„๋กœํผํ‹ฐ์— ๋ฐ”์ธ๋”ฉ ๋˜์–ด ๋ณ€๊ฒฝ๋˜๋ฉด ์ž๋™์œผ๋กœ ์—…๋ฐ์ดํŠธ ํ•ด์ฃผ๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์ž…๋‹ˆ๋‹ค.

 

 

๋ฐฐ๊ฒฝ์ƒ‰, ํฐํŠธ ์‚ฌ์ด์ฆˆ, ํ…์ŠคํŠธ ์ปฌ๋Ÿฌ๋ฅผ ์ „๋‹ฌ ๋ฐ›๋„๋ก ๋งŒ๋“ค์–ด ์ฃผ๊ฒ ์Šต๋‹ˆ๋‹ค.

 

import { Directive, ElementRef, HostListener, Input } from '@angular/core';

@Directive({
  selector: '[appMouseControl]',
})
export class MouseControlDirective {
  @Input('backgroundColor') backgroundColor: string = 'white';
  @Input('fontSize') fontSize: number = 14;
  @Input('textColor') textColor: string = 'black';

  constructor(private el: ElementRef) {}
	...
}

 

์ด์ œ mouse๊ฐ€ ํ•ด๋‹น ์—˜๋ฆฌ๋จผํŠธ์— ๋“ค์–ด์™”์„ ๋•Œ์™€ ๋‚˜๊ฐ”์„ ๋•Œ ์Šคํƒ€์ผ์ด ์ ์šฉ๋˜๊ณ  ํ•ด์ œ๋˜๋Š” ๊ฒƒ์„ ๊ตฌํ˜„ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

@HostListener ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ๊ฐ’์„ ๊ฐ์ง€ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

* @HostListener

 

DOM์—์„œ ํŠน์ • ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ ์‹คํ–‰ํ•  ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•˜๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์ž…๋‹ˆ๋‹ค.

 

 

@HostListener('mouseenter') ๋กœ ๋งˆ์šฐ์Šค๊ฐ€ ํ•ด๋‹น ์—˜๋ฆฌ๋จผํŠธ์— ๋“ค์–ด์™”์„ ๋•Œ ์œ„์—์„œ @Input ๊ฐ’์„ ์ „๋‹ฌ ๋ฐ›์€ ์Šคํƒ€์ผ ๊ฐ’๋“ค์„ ์ ์šฉํ•ด ์ค๋‹ˆ๋‹ค.

 

@HostListener('mouseleave')๋กœ ๋งˆ์šฐ์Šค๊ฐ€ ๋ฐ–์— ๋‚˜๊ฐ”์„ ๋•Œ style์„ ๋ชจ๋‘ ํ•ด์ œํ•ด ์ค๋‹ˆ๋‹ค.

 

import { Directive, ElementRef, HostListener, Input } from '@angular/core';

@Directive({
  selector: '[appMouseControl]',
})
export class MouseControlDirective {
  ...
   @HostListener('mouseenter') onMouseEnter() {
    this.el.nativeElement.style.backgroundColor = this.backgroundColor;
    this.el.nativeElement.style.fontSize = this.fontSize + 'px';
    this.el.nativeElement.style.color = this.textColor;
  }

  @HostListener('mouseleave') onMouseLeave() {
    this.el.nativeElement.style = {};
  }
}

 

component.html

 

์œ„์—์„œ ๋งŒ๋“  ๋””๋ ‰ํ‹ฐ๋ธŒ๋ฅผ ์ ์šฉํ•  ํ…œํ”Œ๋ฆฟ์œผ๋กœ ์ด๋™ํ•ด ์ค๋‹ˆ๋‹ค.

 

์›ํ•˜๋Š” ์—˜๋ฆฌ๋จผํŠธ ํƒœ๊ทธ์— ๋””๋ ‰ํ‹ฐ๋ธŒ ์ด๋ฆ„์„ ์ ์–ด ์ ์šฉํ•ด ์ฃผ๊ณ , ์œ„์—์„œ ๋งŒ๋“  @Input์— ์ „๋‹ฌํ•  ๊ฐ’๋“ค์„ '[]'๋ฅผ ์ด์šฉํ•ด ์ฐจ๋ก€๋กœ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.

 

<h1
  appMouseControl
  [backgroundColor]="'black'"
  [fontSize]="36"
  [textColor]="'white'"
>
  ๋””๋ ‰ํ‹ฐ๋ธŒ ํ…Œ์ŠคํŠธ
</h1>

 

๋””๋ ‰ํ‹ฐ๋ธŒ๋ฅผ ์ ์šฉํ•˜๋ฉด '['๋งŒ ์ž‘์„ฑํ•ด๋„ ์ด๋ฏธ ๋งŒ๋“ค์–ด์ค€ @Input ๊ฐ’๋“ค์„ ๊ณ ๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 


์‹คํ–‰๊ฒฐ๊ณผ

 

๋งˆ์šฐ์Šค๊ฐ€ ๋“ค์–ด์™”์„ ๋•Œ

 

 

๋งˆ์šฐ์Šค๊ฐ€ ๋‚˜๊ฐ”์„ ๋•Œ


์—ฌ๋Ÿฌ ์Šคํƒ€์ผ ํ•œ๋ฒˆ์— ์ ์šฉํ•˜๊ธฐ

 

๋งŒ์•ฝ ์—ฌ๋Ÿฌ ์Šคํƒ€์ผ์„ ํ•œ๋ฒˆ์— ์ ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด @Input ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์— ๊ฐ์ฒด ํ˜•ํƒœ๋ฅผ ๋งŒ๋“ค์–ด ์ค๋‹ˆ๋‹ค.

 

๊ทธ๋ฆฌ๊ณค renderer๋ฅผ ์ด์šฉํ•ด์„œ ์ „๋‹ฌ๋ฐ›์€ ๊ฐ์ฒด ์•ˆ์˜ ๊ฐ’๋“ค์„ ์Šคํƒ€์ผ๋กœ ๋ชจ๋‘ ์ ์šฉ์‹œ์ผœ ์ค๋‹ˆ๋‹ค.

 

directive.ts

 

import {
  Directive,
  ElementRef,
  HostListener,
  Input,
  Renderer2,
} from '@angular/core';

@Directive({
  selector: '[appMouseControl]',
})
export class MouseControlDirective {
  @Input('styles') styles: any = {};

  constructor(private el: ElementRef, private renderer: Renderer2) {}

  @HostListener('mouseenter') onMouseEnter() {
    Object.keys(this.styles).forEach((newStyle) => {
      this.renderer.setStyle(
        this.el.nativeElement,
        `${newStyle}`,
        this.styles[newStyle]
      );
    });
  }

  @HostListener('mouseleave') onMouseLeave() {
    this.el.nativeElement.style = {};
  }
}

 

 

component.html

 

 

@Input๊ฐ’์— ์ „๋‹ฌํ•  ๊ฐ’์„ ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ์ „๋‹ฌํ•ด ์ค๋‹ˆ๋‹ค.

 

<h1
  appMouseControl
  [styles]="{ backgroundColor: 'black', fontSize: '36px', color: 'white' }"
>
  ๋””๋ ‰ํ‹ฐ๋ธŒ ํ…Œ์ŠคํŠธ
</h1>

์‹คํ–‰๊ฒฐ๊ณผ

 

์œ„์™€ ๊ฐ™์ด ์ ์šฉํ•ด๋„ ๊ฐ™์€ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ต๋‹ˆ๋‹ค.

 

๋งˆ์šฐ์Šค๊ฐ€ ๋“ค์–ด์™”์„ ๋•Œ

 

 

๋งˆ์šฐ์Šค๊ฐ€ ๋‚˜๊ฐ”์„ ๋•Œ

728x90
๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€