사용자 정의 템플릿을 제공하여 Angular Component를 풍성하게 만드는 방법을 살펴 보겠습니다. 개발자가 선언한 외부 Row(행) 템플릿을 지원하는 간단한 리스트 Component를 작성하며 시작하겠습니다.
List component
먼저 바인딩된 항목 컬렉션을 표시하는 간단한 리스트 Component를 만듭니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Component({
selector: 'tlist',
template: `
<ul>
<li *ngFor="let item of items">
{{ item.title }}
</li>
</ul>
`
})
exportclass TListComponent {
@Input()
items: any[] = [];
}
이제 메인 응용 프로그램 Component를 업데이트 하거나 다음 예제와 같이 별도의 데모 Component를 만듭니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Component({
selector: 'tlist-demo',
template: `
<h1>Templated list</h1>
<tlist [items]="items"></tlist>
`
})
exportclass AppComponent {
items: any[] = [
{ title: 'Item 1' },
{ title: 'Item 2' },
{ title: 'Item 3' }
];
}
그러면 다음과 같이 정렬되지 않은 HTML 목록이 렌더링됩니다.
Row templates
우리는 객체의 배열에 바인딩하고 정렬되지 않은 표준 HTML리스트를 렌더링하는 간단한 리스트 컴포넌트를 만들었습니다. 그리고 모든 리스트 항목은 title 프로퍼티 값에 바인딩됩니다. 이제 외부 템플릿을 지원하도록 코드를 변경해 보겠습니다. 아래 그림과 같이 코드를 업데이트 합니다.
이제 TListComponent는 자식 컨텐츠에서 정의될 템플릿을 참조합니다. 그리고 템플릿 내용을 받아 각 *ngFor 항목에 적용합니다. 따라서 이 Component를 사용하는 응용 프로그램 개발자는 다음과 같이 전체 Row 템플릿을 정의할 수 있습니다.
1
2
3
4
5
6
7
<tlist [items]="items">
<template>
<li>
Row template content
</li>
</template>
</tlist>
이제 아래 예제와 같이 업데이트합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import { Component } from'@angular/core';
@Component({
selector: 'tlist-demo',
template: `
<div>
<h2>Templated list</h2>
<tlist [items]="items">
<template let-item="$implicit" let-i="index">
<li>[{{i}}] Hello: {{item.title}}</li>
</template>
</tlist>
</div>
`
})
exportclass TListComponentDemo {
items: any[] = [
{ title: 'Item 1' },
{ title: 'Item 2' },
{ title: 'Item 3' }
];
}
각 Row에 대한 기본 데이터 바인딩 컨텍스트에 액세스하기 위해 let-item = "$implicit" 프로퍼티를 사용하여 item 변수에 매핑합니다. 따라서 item은 TListComponentDemo의 items 컬렉션에 있는 항목을 가리키며 title 프로퍼티에 바인딩할 수 있습니다. 또한 let-i = "index"를 통해 i 변수에 Row 인덱스 프로퍼티 값을 할당합니다.
또 다른 개선점은 TListComponent가 더 이상 모든 바인딩된 객체가 title 프로퍼티를 갖도록 강요하지 않는다는 것입니다. 이제 템플릿과 기본 컨텍스트가 모두 응용 프로그램 수준에서 정의됩니다.
변경 사항이 렌더링된 결과는 다음과 같습니다.
동적 Component
또 다른 일반적인 시나리오는 일부 조건에 따라 Component의 내용을 변경하는 것입니다. 예를 들어 아래와 같이 type 프로퍼티 값을 기반으로 다른 하위 Component를 렌더링하는 경우입니다.
런타임에는 세 가지 Component(Fallback된 UnknownDynamicComponent 포함)를 볼 수 있어야합니다. Context 입력란의 텍스트를 변경하면 모든 위젯이 자동으로 업데이트됩니다.
일반적인 사용 사례
정의 파일 (JSON, XML 등)을 기반으로 Form(또는 복합 Component)을 표시해야하는 경우 스키마 또는 상태를 기반으로 최종 컨텐츠를 빌드하는 동적 Component와 여러 동적 컨텐츠 컨테이너에서 빌드된 Form Component를 갖게 될 수 있습니다.
런타임 컴파일
일부 고급 시나리오의 경우 Angular Component 또는 템플릿 편집을 완전히 제어 할 필요가 있을 수 있습니다.
이 장에서는 다음 기능을 구현합니다.
사용자에게 Component 템플릿을 정의하도록 합니다.
Component를 즉석에서 컴파일(사용자 정의 템플릿 + 클래스)합니다.
컴포넌트를 생성하면서 NgModule을 즉시 컴파일합니다.
새로 생성된 Component 표시합니다.
구현은 이전 장의 동적 Component를 기반으로 합니다. 그리고 콘텐츠를 삽입하기위한 전용 자리 표시자가있는 기본 Component가 필요합니다.
위 코드는 사용자 지정 메타 데이터와 선택적으로 Component 클래스를 받습니다. 클래스가 제공되어 있지 않은 경우, 대신 RuntimeComponent를 미리 정의된 name 프로퍼티와 함께 사용됩니다. 이것은 우리가 테스트를 위해 사용할 것입니다. 그런 다음 결과 Component는 제공된 메타 데이터로 장식(Decorate)됩니다.
다음으로, RuntimeComponentModule 모듈은 미리 정의된 CommonModule을 import(필요한 경우 목록을 확장 할 수 있음)하고, declarations 섹션의 일부로 이전에 생성되어 장식(Decorate)된 Component로 만들어집니다.
마지막으로 이 함수는 Angular의 Compiler 서비스를 사용하여 모듈과 포함된 Component를 컴파일합니다. 컴파일된 모듈은 기본 Component 팩토리에 대한 액세스를 제공하며 이는 정확히 우리가 필요로하는 것입니다.
마지막 단계에서는 다음 코드로 Compile 버튼을 연결합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
exportclass RuntimeContentComponent {
compileTemplate() {
let metadata = {
selector: `runtime-component-sample`,
template: this.template
};
let factory = this.createComponentFactorySync(this.compiler, metadata, null);