! 제품 버전을 정확하게 입력해 주세요.
제품 버전이 정확하게 기재되어 있지 않은 경우,
최신 버전을 기준으로 안내 드리므로
더욱 빠르고 명확한 안내를 위해
제품 버전을 정확하게 입력해 주세요!

Angular 앱에서 Web Component 사용하기 > 인사이트

본문 바로가기

MESCIUS 커뮤니티

인사이트 - IT&개발 정보

IT&개발 정보 Angular 앱에서 Web Component 사용하기

페이지 정보

작성자 GrapeCity 작성일 2019-09-09 00:00 조회 5,614회 댓글 0건

본문


 

웹 개발에서 컴포넌트의 역사 


JavaScript 개발자라면 아마도 Web Component에 대해 들어 보셨을 것입니다. Web Component를 사용하면 JavaScript를 사용하여 사용자 지정 HTML 컴포넌트를 정의 할 수 있습니다. 움직이는 춤추는 고양이를 테두리로 감싸는 <my-cat /> 태그를 만들고 싶은가요? Web Component를 사용하여 프레임워크 사용 여부에 관계없이 모든 브라우저에서 작동하도록 만들 수 있습니다.


컴포넌트 기반 웹 개발은 새로운 아이디어는 아닙니다. 거의 웹만큼 오래 되었습니다. 생성하는 모든 사이트에 대해 맞춤형 HTML을 생성하는 대신 컴포넌트를 사용하여 재사용 가능한 빌딩 블록을 생성 할 수 있습니다.


가장 처음으로 널리 사용되었던 웹 앱 개발 컴포넌트는 1996년에 등장한 NeXT Software의 WebObjects 였고, 몇 년 후 JavaServer Faces와 ASP.NET Web Forms가 시장에 출시되었습니다. 이러한 모든 프레임워크가 HTML 서버측을 생성하여 브라우저로 전송했지만, 최신 프론트엔드 프레임워크의 사용자는 WebObjects, JSF 및 Web Forms에서 그 개념을 매우 친숙하게 찾을 수 있습니다.


결국 브라우저가 발전하고 JavaScript 엔진의 기능이 향상됨에 따라 개발자는 단일 페이지 응용 프로그램 (SPA) 작성을 실험하기 시작했습니다. 개발자는 HTML 서버 측을 생성하는 대신 브라우저에서 클라이언트 측을 생성하기 시작했습니다. 2006년 처음 등장한 컴포넌트 기반 클라이언트 측 프레임워크 중 하나는 Google Web Toolkit (일반적으로 GWT라고 함)입니다. GWT는 컴포넌트 기반 프레임워크였으며 Java-to -JavaScript 컴파일러이기도 했습니다.


2010년에는 BackboneJS와 KnockoutJS와 같이 보다 대중적인 컴포넌트 프레임워크가 등장했습니다. GWT와 달리 순수한 JavaScript 프레임워크였습니다. 2012년에는 AngularJS가 나타났으며, 이는 클라이언트 측 컴포넌트 프레임워크의 인기가 가속화 된 시기입니다. 몇 년 안에 React와 Vue가 나타났으며 많은 웹 개발자에게 컴포넌트 기반 SPA가 새로운 웹 앱을 개발하는 기본 방법이 되었습니다.


이러한 모든 클라이언트 측 프레임워크에는 한 프레임워크에서 작성된 컴포넌트는 다른 프레임워크에서 쉽게 사용할 수 없다는 단점이 있습니다. 한 프레임워크에 정착하는 회사는 일반적으로 모든 애플리케이션에 해당 프레임워크를 사용하기 때문에 그렇게 큰 문제가 되지는 않습니다. 그러나 재사용 가능한 프런트엔드 컴포넌트 라이브러리를 만들려는 회사나 오픈 소스 프로젝트 및 개인에게는 다양한 인기 있는 프레임워크가 도전 과제로 다가옵니다. 어떻게 원하는 모든 프레임워크에 대해 작업을 복제하지 않고도 누구나 사용할 수 있는 컴포넌트를 만들 수 있을까요?


Web Component가 이에 대한 솔루션을 제공합니다. Web Component는 어떤 프레임워크에서도 사용될 수 있는 사용자 정의 HTML 요소를 정의하는 브라우저 네이티브 방식입니다.  심지어는 프론트엔드 프레임워크를 전혀 사용하지 않는 사용자 정의 HTML요소도 정의합니다. 이 포스팅에서는 Angular 8에서 Web Component를 사용하는 방법을 살펴볼 것입니다. 먼저, 간단한 Web Component 몇 가지를 만드는 과정을 알아보겠습니다.


전제 조건


이 포스팅은 최신 Angular 개발에 익숙한 사람들을 대상으로 합니다. Angular 8을 사용할 것이지만 Angular 4 이상에 익숙하다면 따라가는 데 큰 어려움은 없을 것입니다.


Angular 앱에서 사용할 고유 한 Web Component를 만들 것이지만 시작하기 전에 Web Component를 심층적으로 살펴볼 시간이 없기 때문에, Web Component의 작동 방식에 익숙하다고 가정하겠습니다.


다행히도 Web Component 사양 사이트  Web Component 를 만들고 사용하는 기본 사항에 대해 자세히 설명하고 있습니다. 대부분의 소프트웨어 사양과 달리 이 사양은 따르기 쉽습니다. 일반 영어로 모든 것을 설명하고 있으며, 많은 코드 샘플을 포함하고 있습니다.


Web Component 생성


Web Component를 Angular 앱에 넣기 전에 사용할 Web Component가 필요합니다. 기존 컴포넌트 라이브러리에서 가져올 수도 있지만, 더 재미 있는 방법을 사용해보겠습니다.


간단한 카운터 컴포넌트 두 개를 만들겠습니다. 첫번째 컴포넌트는 필수 요소이고, 이 컴포넌트에는 카운터를 늘리거나 줄이기 위해 호출해야 하는 객체 지향 API가 있습니다.


두 번째 컴포넌트는 선언적 카운터 컴포넌트입니다. 이 컴포넌트의 계수 값은 속성을 통해 전달됩니다. 이 외부 값에 의존하며 값을 늘리거나 줄일 수 없습니다. 이것은 쓸모 없는 것처럼 들리지만 컴포넌트가 전달 된 데이터를 표시하기만 하는 경우 선언적 컴포넌트가 일반적입니다. Wijmo 게이지(Gauge) 컴포넌트가 이 유형의 좋은 예입니다.


이제 커스텀 컴포넌트 코드에 대해 알아 보겠습니다.


이 실습을 쉽게 할 수 있도록 모든 코드를 StackBlitz에 넣었습니다. 웹 브라우저에서 보고 실행할 수 있습니다.


시작하려면 src / app / web-components 폴더에 있는 ImperativeCounter.ts 파일살펴 보겠습니다.


class ImperativeCounter extends HTMLElement {  
  private readonly shadow: ShadowRoot;  
  private currentCount: number = 0;  

  constructor() {  
    super();  
    this.shadow = this.attachShadow({ mode: 'open'});  
    this.update();  
  }

  update() {  
    const template = `  
      <style>  
        .counter {  
          font-size: 25px;  
        }  
      </style>  
      <div class="counter">  
        <b>Count:</b> ${this.currentCount}  
      </div>  
    `;  
    this.shadow.innerHTML = template;  
  }

  increment(){  
    this.currentCount++;  
    this.update();  
  }

  decrement() {  
    this.currentCount--;  
    this.update();  
  }  
}

window.customElements.define('i-counter', ImperativeCounter);


모든 Web Component와 마찬가지로 HTMLElement를 확장하여 시작합니다. 이 작업을 수행해야 하며, 수행하지 않으면 브라우저에서 컴포넌트를 등록할 수 없습니다.


다음으로, 두 가지 인스턴스 변수를 만듭니다.


  • shadow : Web Component의 shadow DOM을 보유
  • currentCount : 카운터의 현재 값을 저장

     

그런 다음, 생성자는 shadow DOM을 생성하여 shadow에 저장합니다. 생성자는 update 메소드를 호출하여 완료됩니다.


업데이트에서는 currentCount 값이 포함된 요소의 HTML 템플릿을 정의합니다. 그런 다음 템플릿 문자열을 shadow DOM의 innerHTML속성에 할당합니다.


명령 카운터 클래스는 증가 및 감소 방법을 정의함으로써 완료됩니다. 이러한 메소드는 단순히  currentCount 값을 늘리거나 줄인 다음 update를 호출하여 컴포넌트의 HTML에 새로운 currentCount값을 표시합니다.


클래스 선언 외부에서 window.customElements.define을 호출하여 반짝이는 새 컴포넌트를 브라우저에 등록합니다. 이 과정을 거치지 않으면, 카운터 컴포넌트를 사용할 수 없습니다.


이제 선언적 카운터 컴포넌트를 살펴 보겠습니다. 명령 카운터와 유사합니다.


class DeclarativeCounter extends HTMLElement {  
  private readonly shadow: ShadowRoot;  
  private currentCount: number = 0;

  constructor() {  
    super();  
    this.shadow = this.attachShadow({ mode: 'open'});  
  }  

  static get observedAttributes() {  
      return ['count']  
  }

  connectedCallback() {  
      this.currentCount = parseInt(this.getAttribute('count')) || 0;  
      this.update();  
  }

  attributeChangedCallback(attrName, oldVal, newVal) {  
      this.currentCount = newVal;  
      this.update();  
  }

  update() {  
    const template = `  
      <style>  
        .counter {  
          font-size: 25px;  
        }  
      </style>  
      <div class="counter">  
        <b>Count:</b> ${this.currentCount}  
    `;  
    this.shadow.innerHTML = template;  
  }  
}

window.customElements.define('d-counter', DeclarativeCounter);


명령 카운터에서와 마찬가지로, shadow DOM 루트 및 카운터의 현재 카운트 값에 대한 인스턴스 변수를 정의하는 것으로 시작하겠습니다.


생성자는 비슷하지만 update 메소드를 호출하지 않습니다. 기다렸다가 count 속성을 통해 값이 컴포넌트에 전달되었는지 확인할 것입니다. 이 값은 컴포넌트의 생성자가 호출 될 때 사용할 수 없습니다. 대신 Web Component 수명주기 메소드인connectedCallback을 사용합니다.


이 메소드는 컴포넌트가 DOM에 삽입된 후에 호출됩니다. 컴포넌트의 connectedCallback메소드를 살펴보면 컴포넌트의 count 속성 값을 읽고 currentCount의 값을 설정하는 데 사용된다는 것을 알 수 있습니다. 그런 다음 update를 호출하여 컴포넌트를 렌더링합니다.


컴포넌트를 살펴보면 명령형 카운터와 다른 두 가지 속성을 볼 수 있습니다.


  • 정적 속성 observedAttributes
  • attributeChangedCallback메서드  

이 두가지는 Web Components API의 두 부분입니다.


observedAttributes는 컴포넌트가 변경 될 때 알림을 수신하고자 하는 속성 이름의 리스트를 브라우저에 제공합니다. 이는 컴포넌트의 최종 사용자가 원하는 만큼 많은 속성을 추가할 수 있고 브라우저에서 사용하지 않을 컴포넌트의 변경 알림을 보내는 것은 리소스 낭비가 될 수 있으므로 유용합니다.


attributeChangedCallback메소드는 속성 중 하나가 attributeChangedCallback변경 사항 목록에 들어갈 때마다 브라우저에서 호출됩니다 . 이 경우 count는 알림을 받는 유일한 속성입니다. 따라서 메서드가 호출되면 새 currentCount값으로 업데이트 한 다음 update를 호출하여 컴포넌트를 다시 렌더링합니다.


Angular에서 Web Component 사용하기


컴포넌트를 만들었으니 이제 Angular에서 컴포넌트를 사용할 차례입니다. 지금까지 수행한 모든 작업을 마친 후 Angular에서 Web Component를 사용하는 것은 매우 쉽습니다.


StackBlitz 프로젝트에서 app.module.ts를 엽니다.


import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';  
import { BrowserModule } from '@angular/platform-browser';  
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';

@NgModule({  
  imports:      [ BrowserModule, FormsModule ],  
  declarations: [ AppComponent ],  
  bootstrap:    [ AppComponent ],  
  schemas: [ CUSTOM_ELEMENTS_SCHEMA ]  
})  
export class AppModule { }


전반적으로, Angular CLI가 생성 할 bare-bone 앱 모듈과 매우 유사합니다. 그러나 몇 가지 중요한 차이점이 있으므로 살펴 보겠습니다.


가장 먼저 주목할 것은 @ angular / core에서 CUSTOM_ELEMENTS_SCHEMA를 가져 오는 것입니다. Angular는 스키마를 사용하여 모듈 내에서 허용되는 요소 이름을 결정합니다. 사용자 지정 요소 스키마를 가져 오지 않으면 Angular 템플릿 컴파일러는 이해하지 못하는 요소 이름이 발견 될 때 오류를 보고하기 때문에 이 과정이 필요합니다.


또한 NgModule 데코레이터에 schemas 속성을 추가하여 Angular에게 앱 모듈에서 사용자 지정 요소 스키마를 사용하도록 지시했습니다.


다음으로 main.ts를 열어 두 가지 import를 추가합니다.


import "./app/web-components/ImperativeCounter.ts";  
import "./app/web-components/DeclarativeCounter.ts";


위의 코드는 우리가 만든 카운터 컴포넌트를 가져와서 브라우저에 등록합니다. 이 과정이 없으면 Angular 앱에서 컴포넌트를 사용할 수 없으므로 아주 중요합니다!


이제, app.component.html에서 Web Component가 어떻게 사용되는지 살펴 보겠습니다.


<h5>Imperative Counter</h5>  
<div class="counter-box">  
  <i-counter #iCounter></i-counter>  
</div>  
<h5>Declarative Counter</h5>  
<div class="counter-box">  
  <d-counter [count]="count" #dCounter></d-counter>  
</div>  
<button (click)="increment()" class="btn btn-primary">Increment</button>  
<button (click)="decrement()"class="btn btn-primary">Decrement</button>


보시다시피 브라우저에 등록한 i-counter d-counter 라는 이름의 태그를 사용하여 Web Component를 렌더링합니다. 선언 카운터의 경우 초기 카운트 속성을 컴포넌트의 카운트 변수 값에 바인딩합니다.


컴포넌트에 추가된 내용도 추가했습니다. : #iCounter #dCounter.


잠시 후에 살펴 보겠지만,이 태그를 사용하면 Angular 컴포넌트가 이러한 요소에 대한 직접 참조를 가져와서 업데이트 할 수 있습니다.


마지막으로 Web Component 카운터의 값을 변경하기 위해 앱 컴포넌트의 메서드를 호출하는 증가 및 감소 버튼이 있습니다.


이제 app.component.ts 를 살펴 보겠습니다.


import { Component, ElementRef, ViewChild  } from '@angular/core';

@Component({  
  selector: 'my-app',  
  templateUrl: './app.component.html',  
  styleUrls: [ './app.component.css' ]  
})  
export class AppComponent  {  
  private count: number = 0;  
  @ViewChild("iCounter") iCounter: ElementRef;  
  @ViewChild("dCounter") dCounter: ElementRef;

  increment() {  
    this.count++;  
    this.iCounter.nativeElement.increment();  
    this.dCounter.nativeElement.setAttribute("count", this.count);  
  }

  decrement() {  
    this.count--;  
    this.iCounter.nativeElement.decrement();  
    this.dCounter.nativeElement.setAttribute("count", this.count);  
  }  
}

 

Component, ElementRef ViewChild 를 @angular / core 에서 import 하여 시작합니다. Web Component의 값을 변경하기 위해 직접 우리의 Web Component를 조작해야 하기 때문에 ElementRef ViewChild가 필요합니다. 네이티브 Angular 컴포넌트를 사용하는 것보다 조금 낯설 수는 있지만 아주 쉽습니다.


클래스 내부에 현재 카운터 값을 저장하기 위해 인스턴스 변수를 추가합니다. 그런 다음 ViewChild 데코레이터를 사용하여 템플릿에서 방금 본 태그를 사용하여 두 Web Component에 대한 ElementRefs를 가져옵니다. ElementRef인스턴스를 사용하면 기본 고유 요소를 직접 사용할 수 있습니다. 현재 실습의 경우, 이러한 요소는 DOM 노드를 의미합니다.


다음으로 증가 및 감소 메소드가 있습니다. 이 메소드는 마법이 일어나는 곳입니다. 두 메소드 모두 컴포넌트의 개수 변수를 변경한 다음 새 값을 사용하도록 Web Component를 업데이트합니다. 명령형 카운터의 경우 증가 및 감소 메소드를 호출합니다. 선언 카운터의 경우 DOM의 setAttribute메소드를 사용하여 카운터 값을 업데이트합니다.


여기까지가 전부입니다! 직접 만든 Web Component를 사용하여 완벽하게 작동하는 Angular 앱이 완성되었습니다. 최종 결과는 여기에서 확인할 수 있습니다 .


Angular 앱에서 Web Component 사용


지금까지 Web Component에 대해 간단히 살펴보고, Web Component를 Angular 앱에서 사용하는 방법을 배웠습니다.


이제 모든 Angular 애플리케이션에 Web Component를 추가 할 수 있으며 사용자는 그 어느 때보다 만족스러워할 것입니다. 이제 애플리케이션에서 Angular 컴포넌트만을 사용하지 않아도 됩니다. Angular Material도 훌륭하지만 Google의 Material Web Components 중 하나가 앱에 더 적합하다는 것을 알 수 있습니다.


프레임워크에 구애받지 않는 Web Component를 찾고 계신가요?


- Wijmo : JavaScript 기반 Chart, Grid, Input, UI 컨트롤 

- SpreadJS : JavaScript 기반 MS Excel 스프레트 시트



  • 페이스북으로 공유
  • 트위터로  공유
  • 링크 복사
  • 카카오톡으로 보내기

댓글목록

등록된 댓글이 없습니다.

메시어스 홈페이지를 통해 제품에 대해서 더 자세히 알아 보세요!
홈페이지 바로가기

인기글

더보기
  • 인기 게시물이 없습니다.
메시어스 홈페이지를 통해 제품에 대해서 더 자세히 알아 보세요!
홈페이지 바로가기
이메일 : sales-kor@mescius.com | 전화 : 1670-0583 | 경기도 과천시 과천대로 7길 33, 디테크타워 B동 1107호 메시어스(주) 대표자 : 허경명 | 사업자등록번호 : 123-84-00981 | 통신판매업신고번호 : 2013-경기안양-00331 ⓒ 2024 MESCIUS inc. All rights reserved.