[]
        
(Showing Draft Content)

Angular Components

Angular 구성 요소

  • 10. * 버전을 포함하여 Angular 버전 2.2.1 이상을 지원합니다 .


Wijmo 컴포넌트는 Angular 템플릿 마크업에서 Wijmo 컨트롤을 사용할 수 있게 해줍니다. TypeScript 클래스 상속 기능 측면에서 Wijmo Angular 컴포넌트는 자신이 나타내는 컨트롤 클래스를 "확장"합니다. 즉, Wijmo 컴포넌스에 대한 참조를 획득할 때, 참조된 인스턴스는 모든 속성, 이벤트 및 메서드를 가진 Wijmo 컨트롤이자 동시에 Angular 컴포넌트입니다. Wijmo 컴포넌트는 컨트롤 클래스를 확장하고 Angular 템플릿 마크업에서 사용할 수 있도록 필요한 기능을 추가하며, 완전한 단방향 및 양방향 속성 바인딩과 이벤트 바인딩을 지원합니다. 이 통합은 원활하게 이루어지며, Wijmo 컨트롤, Wijmo Angular 컴포넌트 및 Angular 자체가 모두 같은 TypeScript 언어로 작성되어 있습니다.


Wijmo Angular 2 컴포넌트는 npm 패키지 집합으로 제공되며, 각 핵심 라이브러리 패키지당 하나의 패키지가 있으며 이름에 "angular2"라는 단어가 포함되어 있습니다. 예를 들어, "wijmo.angular2.grid" 패키지는 핵심 "wijmo.grid" 패키지의 컨트롤에 대한 컴포넌트를 나타냅니다. 패키지는 별도로 설치하거나 "@mescius/wijmo.angular2.all" 그룹 패키지를 사용하여 모두 함께 설치할 수 있습니다.


npm install @mescius/wijmo.angular2.all

Wijmo의 NPM 패키지에 대한 자세한 내용은, 해당 주제 참고해주세요.


그런 다음 ESM import 문을 사용하여 모듈을 가져올 수 있습니다. 예를 들어 이 import 문은 "wijmo.angular2.grid"모듈의 내용을 가져옵니다.

import * as wjGrid from "@mescius/wijmo.angular2.grid";

Angular CLI

단계별 지침은 이 블로그 를 참조하십시오 .

Wijmo 컴포넌트 가져 오기

이 설정을 사용하면, Wijmo Angular 모듈을 가져 와서 포함된 구성 요소 및 지시문을 사용할 수 있습니다. 예를 들어, 이 코드는 WjFlexGrid 구성 요소를 MyCmp 컴포넌트의 템플릿에 추가하고 flex 속성은 추가된 그리드에 대한 참조를 포함합니다.

import { Component, ViewChild } from '@angular/core'; 
import { WjGridModule, WjFlexGrid } from '@mescius/wijmo.angular2.grid'; 

 @Component({ 
  template: '<wj-flex-grid #flex [itemsSource]="data"></wj-flex-grid>', 
  selector: 'my-cmp', 
  imports: [WjGridModule], 
  standalone: true 
}) 

export class MyCmp { 
data: any[]; 
@ViewChild('flex') flex: WjFlexGrid; 
} 

이전에는 Wijmo 컴포넌트를 통합하기 위해 NgModules를 사용해야 했으며, 이로 인해 추가적인 보일러플레이트 코드가 필요했습니다.

하지만 이제 독립형 컴포넌트를 사용하면, 컴포넌트 데코레이터에서 필요한 Wijmo 모듈을 직접 가져올 수 있어 NgModules의 필요성이 제거되었습니다.

Angular에서 독립형 컴포넌트로 Wijmo의 FlexGrid를 사용할 때는 @mescius/wijmo.angular2.grid에서 WjGridModule WjFlexGrid를 가져와야 합니다. 또한 필요에 따라 다른 Angular 핵심 모듈도 가져와야 합니다.

Wijmo CSS 추가

Wijmo 컨트롤이 올바르게 보이고 작동하려면 Wijmo CSS 파일을 응용 프로그램에 로드 해야 합니다. 스타일은 @mescius/wijmo.styles npm 패키지로 제공됩니다. 두 가지 주요 CSS 파일이 있습니다.

  • wijmo.css- 모든 Wijmo 컨트롤에 대한 스타일 포함

  • wijmo-core.css- 엔터프라이즈 컨트롤 스타일이 포함되지 않은 wijmo.css의 독립 버전입니다.

원하는대로 다음 위치 중 하나에서 Angular CLI 애플리케이션에서 스타일을 로드할 수 있습니다.

기본 styles.css 파일

파일 상단에 CSS import 문을 추가하십시오.

@import "@mescius/wijmo.styles/wijmo.css";


코드에서 Wijmo 컨트롤 만들기

Angular 용 Wijmo 컴포넌트(component) 는 템플릿 마크업에 사용하기 위한 것입니다. 코드에서 Wijmo 컨트롤을 만들려면 컴포넌트 대신, Core 모듈의 Wijmo 컨트롤 을 사용해야 합니다. core 모듈은 해당 Angular interop 모듈과 이름이 동일하지만 이름에 "angular2"단어가 없습니다.

예를 들어, 이 코드는 코드에서 FlexGrid 컨트롤을 만듭니다:

import { FlexGrid } from "@mescius/wijmo.grid";
let flex = new FlexGrid("#host_element");

WjFlexGrid 구성 요소 대신 FlexGrid 컨트롤을 가져오고 '@mescius/wijmo.angular2.grid' 대신 '@mescius/wijmo.grid'모듈에서 가져옵니다.

Angular 마크업 구문

Wijmo Angular 컴포넌트는 템플릿 마크업에서 지정하기 위해 일관된 명명 규칙을 사용합니다. 컴포넌트에 사용되는 HTML 요소 및 특성 이름은 다음과 같은 간단한 규칙을 사용하여 컴포넌트 클래스 및 멤버 이름에서 쉽게 추론 할 수 있습니다.

  • Wijmo 컴포넌트를 나타내는 HTML 요소 이름은 소문자 대시 구문을 사용하여 지정됩니다. 예를 들어, WjInputNumber 컴포넌트는 wj-input-number 로 명명됩니다:

<wj-input-number [(value)]="amount"></wj-input-number>
  • Wijmo 속성 지시문(directives) 은 클래스 이름으로 camel case(낙타 문자) 형식을 사용합니다. 즉, 첫 문자가 소문자인 클래스 이름입니다. 예를 들어, WjFlexGridCellTemplate 지시문은 wjFlexGridCellTemplate 속성을 사용하여 정의됩니다.

<template wjFlexGridCellTemplate [cellType]="'Cell'"></template>
  • Wijmo 컴포넌트 속성 및 이벤트를 나타내는 특성의 이름은 컴포넌트 클래스 인터페이스에서 노출된 속성 및 이벤트 이름과 정확히 일치합니다. 속성 이름은 단방향 바인딩 (예 : [isReadOnly] )의 경우 대괄호로 묶어야하고 양방향 바인딩의 경우 괄호와 괄호 (예 : [(value)] )로 묶어야합니다 . 이벤트 이름은 괄호로 묶어야합니다 (예 : (valueChanged) ). 예를 들면 다음과 같습니다.

    <wj-input-number
        [(value)]="amount" // two-way binding to a component property
        [format]="'n0'" // one-way binding to string
        [isReadOnly]="true" // one-way binding to boolean
        (valueChanged)="valueChanged($event)"> // event binding
    </wj-input-number>

바인딩 표현식은 지정된 특성 유형과 동일한 유형의 값으로 평가되어야 합니다. 위의 예제에서 형식(format) 문자열 유형 특성에는 작은 따옴표로 묶인 'n0' 이 지정되며, 이는 문자열 리터럴을 나타냅니다. 따옴표를 생략하고 n0을 지정하면, 이러한 표현식은 속성 이름으로 처리됩니다. 마찬가지로, isReadOnly의 부울(boolean) 속성에 따옴표 없이 true 값을 설정합니다. 반면에, * 작은 따옴표로 둘러싸인 **'true'**값은 문자열의 문자를 나타내는 것입니다.

이벤트 바인딩 세부 사항

Wijmo 이벤트 핸들러는 sender 및 event 인수의 두 매개 변수를 가진 함수로 정의됩니다. Angular EventEmitter 구현은 이벤트 개시자에서 구독자에게 단일 매개변수만 전달할 수 있게 하며, 템플리트 마크업에서 $event 로컬 변수의 값으로 액세스 할 수 있습니다. Wijmo 이벤트는 이 매개변수에서 이벤트 인수를 전달합니다. 예를 들면 다음과 같습니다.

<wj-flex-grid 
    [itemsSource]="data"
    (deletingRow)="beforeDelete($event)"> // $event contains CellRangeEventArgs object here
</wj-flex-grid>

TypeScript/JavaScript 코드에서 Wijmo 컨트롤 이벤트를 구독함에 따라, 이벤트 핸들러에서 추가적으로 sender를 받고자하는 경우, 로컬 템플릿 변수를 컴포넌트에 추가하고 이벤트 인자와 함께 이벤트 핸들러에 전달 하기만 하면 됩니다 :

<wj-flex-grid #flex // 'flex' local variable references the grid component instance
    [itemsSource]="data"
    (deletingRow)="beforeDelete(flex, $event)"> // pass sender ('flex') and event arguments ($event) to the handler
</wj-flex-grid>

"초기화" 이벤트

모든 Wijmo Angular 컴포넌트에는 컨트롤이 페이지에 추가되고 초기화된 후 발생하는 "초기화(initialized)"이벤트가 포함됩니다.


이 이벤트를 사용하여 마크업에서 속성을 설정하는 것 외에도 추가적인 초기화를 수행 할 수 있습니다. 예를 들면 다음과 같습니다.

<wj-flex-grid #flex (initialized)="initGrid(flex)">
</wj-flex-grid>
// implementation
export class AppComponent {
    constructor() {
        this.data = ...;
    }
  
    // add custom merge manager to the FlexGrid
    initGrid(flex) {
        flex.mergeManager = new CustomMerge(flex);
    }
}

Angular 9 (Ivy) 이상의 속성 초기화 순서

Angular 8 이하에서는 Wijmo 구성 요소에서 속성 초기화 순서가 내부적으로 정의되었으므로 컴포넌트의 요소에 지정된 속성 지정 순서와 상관없이 항상 동일한 순서로 초기화됩니다. 기술적으로 초기화 순서는 @Component 데코레이터의 inputs 속성에 있는 속성 이름의 순서에 따라 결정 됩니다.


Angular 9에서는 상황이 변경되었으며, 기본적으로 이 프레임워크에서 사용되는 새로운 Ivy 컴파일러가 등장했습니다. 이제 속성은 개발자가 요소에 지정한 순서대로 정확하게 초기화됩니다. 따라서 Angular 9부터는 올바른 속성 초기화 순서를 지정하는 것이 컴포넌트를 사용하는 개발자의 책임입니다.


예를 들어, 아래 마크업을 고려해 보겠습니다.

<wj-list-box [selectedIndex]="3" [itemsSource]="data"></wj-list-box>

Angular 8 이하에서 올바르게 작동합니다 - 네번째 항목이 선택된 상태로 목록이 나타납니다.


하지만, Angular 9 이상에서는 그렇지 않습니다. 첫 번째 항목이 선택된 상태로 목록이 표시되고 selectedIndex 속성에 대한 할당이 무시됩니다. 이는 selectedIndex 가 여기 itemsSource 앞에 정의 되어 있고, 컨트롤이 itemsSource 속성을 통해 항목 배열을 받기 전에 할당되므로 현재 인덱스 3이 있는 항목이 없기 때문입니다.


Angular 8 이하에서는 초기화 순서가 구성 요소에 의해 내부적으로 정의되어 selectedIndex 가 항상 itemsSource 에 할당됩니다 .


이 문제를 해결하고, Angular 9 및 다른 모든 버전에서 예상한대로 동작하도록 마크업을 하려면, 우리는 selectedIndex 정의를 itemsSource 에 정의할 필요가 있습니다:

<wj-list-box [itemsSource]="data" [selectedIndex]="3"></wj-list-box>

또 다른 좋은 예는 [isRequired] = "false"속성을 사용하여 구성 요소에서 null 값을 허용하는 것입니다. 이 마크 업은 Angular 9에서 예외를 발생시킵니다 (그러나 Angular 8에서는 작동합니다).

<wj-input-number [value]="null" [isRequired]="false"></wj-input-number>

isRequired가 false로 설정되기 전에 null 값 지정 시도가 수행되기 때문입니다.


올바른 정의는 다음과 같습니다.

<wj-input-number [isRequired]="false" [value]="null"></wj-input-number>

이것은 모든 Angular 버전에서 작동합니다.

Angular 8 이하에서 ES 모듈 비활성화

wijmo.angular2. * 모듈의 ESM 버전은 빌드 5.20202.699 (2020 년 7 월 22 일 릴리스)부터 기본적으로 사용됩니다. Angular 버전 8 이하를 기반으로 하는 프로젝트에서는 일부 특정 사용 시나리오에서 문제가 발생할 수 있습니다.


이러한 사용 사례의 예는 wjFlexGridCellTemplate 또는 wjItemTemplate 지시자를 포함하는 사용자 정의 컴포넌트 템플릿과 함께, Wijmo 컴포넌트에서 상속된 컴포넌트가 있는 경우입니다. 또는 Menu 컴포넌트가 있는 경우입니다. 해당 문제는 Angular AOT 컴파일러(ViewEngine)에 의해 발생하므로 프로덕션 번들에서만 발생한다 점을 유의하십시오.


이 문제가 발생하면 wijmo-esm 유틸리티를 사용하여 달성 할 수 있는, wijmo.angular2. * 모듈의 ESM 버전을 비활성화해야 합니다. 일반적으로 옵션을 전달하지 않고 이 유틸리티를 호출합니다. 이 경우 프로젝트에 사용된 Angular 버전을 자동으로 감지하여 Wijmo ESM 모듈이 8 이하인 경우 비활성화하거나, 버전이 9 이상인 경우 활성화합니다. ESM이 비활성화되면 Angular는 CommonJS 모듈을 사용합니다.


-disable 또는 -enable 옵션을 지정하여 무조건 ESM 모듈을 비활성화하거나 활성화 할 수도 있습니다. 도구는 프로젝트의 node modules/.bin_ 폴더에 설치됩니다 . 이를 사용하는 권장 방법은 npm "postinstall" 이벤트에서 호출하는 것입니다.

    "scripts": {
        "postinstall": "wijmo-esm",
        ..........
    }

수동으로 실행하려면 프로젝트 패키지의 npm 스크립트에 추가하십시오.

    "scripts": {
        "wijmo-esm": "wijmo-esm",
        ..........
    }

그 후 다음 명령을 사용하여 실행할 수 있습니다.

 npm run wijmo-esm

또는 옵션을 지정해야하는 경우 :

 npm run wijmo-esm -- -disable

사용 가능한 옵션에 대한 도움말 정보를 표시하려면 다음 명령을 실행하십시오.

 npm run wijmo-esm -- -help

도구의 실행 파일은 프로젝트의, 해당 경로 아래에 있습니다.

node_modules/@mescius/wijmo.angular2.directivebase/tools/wijmo-esm.js