Angular에서 동적으로 구성요소 추가 및 제거
현재의 공식 문서는 다음과 같이 구성 요소를 동적으로 변경하는 방법만 보여줍니다.<ng-template>
태그. https://angular.io/guide/dynamic-component-loader
제가 달성하고자 하는 것은 다음과 같은 세 가지 구성요소가 있다고 가정해 보겠습니다.header
,section
,그리고.footer
다음 선택기를 사용합니다.
<app-header>
<app-section>
<app-footer>
그런 다음 각 구성 요소를 추가하거나 제거하는 6개의 버튼이 있습니다.Add Header
,Add Section
,그리고.Add Footer
그리고 내가 클릭할 때Add Header
페이지가 추가됩니다.<app-header>
페이지에 다음 내용을 포함하도록 렌더링하는 페이지로 이동합니다.
<app-header>
그리고 나서 내가 클릭하면Add Section
이제 페이지에 다음 항목이 포함됩니다.
<app-header>
<app-section>
<app-section>
그리고 내가 클릭하면Add Footer
이제 페이지에 다음 구성 요소가 모두 포함됩니다.
<app-header>
<app-section>
<app-section>
<app-footer>
Angular에서 이것을 달성하는 것이 가능합니까?참고:ngFor
페이지에 다른 구성 요소가 아닌 동일한 구성 요소만 추가할 수 있기 때문에 제가 찾고 있는 솔루션이 아닙니다.
편집:ngIf
그리고.ngFor
템플릿이 이미 정해져 있기 때문에 제가 찾고 있는 해결책은 아닙니다.제가 찾고 있는 것은 한 무더기의component
애잔array
의component
s의 인덱스를 추가, 제거 및 변경할 수 있습니다.array
쉽게.
EDIT 2: 좀 더 명확하게 하기 위해, 그 이유에 대한 또 다른 예를 들어 보겠습니다.ngFor
작동하지 않습니다.다음과 같은 구성 요소가 있다고 가정합니다.
<app-header>
<app-introduction>
<app-camera>
<app-editor>
<app-footer>
이제 새로운 구성 요소가 등장합니다.<app-description>
사용자가 와 사이에 삽입하려는 항목<app-editor>
.ngFor
반복하고 싶은 동일한 구성 요소가 있는 경우에만 작동합니다.하지만 다른 구성 요소에 대해서는,ngFor
여기서 실패합니다.
다음을 사용하여 동적으로 구성 요소를 생성하여 달성하려는 작업을 수행할 수 있습니다.ComponentFactoryResolver
그리고 나서 그것들을 주입합니다.ViewContainerRef
동적으로 이를 수행하는 한 가지 방법은 구성 요소의 클래스를 구성 요소를 만들고 주입할 함수의 인수로 전달하는 것입니다.
아래 예를 참조하십시오.
import {
Component,
ComponentFactoryResolver, Type,
ViewChild,
ViewContainerRef
} from '@angular/core';
// Example component (can be any component e.g. app-header app-section)
import { DraggableComponent } from './components/draggable/draggable.component';
@Component({
selector: 'app-root',
template: `
<!-- Pass the component class as an argument to add and remove based on the component class -->
<button (click)="addComponent(draggableComponentClass)">Add</button>
<button (click)="removeComponent(draggableComponentClass)">Remove</button>
<div>
<!-- Use ng-template to ensure that the generated components end up in the right place -->
<ng-template #container>
</ng-template>
</div>
`
})
export class AppComponent {
@ViewChild('container', {read: ViewContainerRef}) container: ViewContainerRef;
// Keep track of list of generated components for removal purposes
components = [];
// Expose class so that it can be used in the template
draggableComponentClass = DraggableComponent;
constructor(private componentFactoryResolver: ComponentFactoryResolver) {
}
addComponent(componentClass: Type<any>) {
// Create component dynamically inside the ng-template
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(componentClass);
const component = this.container.createComponent(componentFactory);
// Push the component so that we can keep track of which components are created
this.components.push(component);
}
removeComponent(componentClass: Type<any>) {
// Find the component
const component = this.components.find((component) => component.instance instanceof componentClass);
const componentIndex = this.components.indexOf(component);
if (componentIndex !== -1) {
// Remove component from both view and array
this.container.remove(this.container.indexOf(component));
this.components.splice(componentIndex, 1);
}
}
}
주의:
나중에 구성 요소를 쉽게 제거하려면 로컬 변수에서 해당 구성 요소를 추적할 수 있습니다.
this.components
또는 내부의 모든 요소를 루프할 수 있습니다.ViewContainerRef
.구성요소를 항목 구성요소로 등록해야 합니다.모듈 정의에서 구성 요소를 항목 구성 요소(
entryComponents: [DraggableComponent]
).
실행 예: https://plnkr.co/edit/mrXtE1ICw5yeIUke7wl5
자세한 내용은 https://angular.io/guide/dynamic-component-loader 에서 확인하시기 바랍니다.
Angular v13 이상 - DOM에 동적 구성 요소를 쉽게 추가할 수 있는 방법
parent.component.html
<ng-template #viewContainerRef></ng-template>
parent.component.ts
@ViewChild("viewContainerRef", { read: ViewContainerRef }) vcr!: ViewContainerRef;
ref!: ComponentRef<YourChildComponent>
addChild() {
this.ref = this.vcr.createComponent(YourChildComponent)
}
removeChild() {
const index = this.vcr.indexOf(this.ref.hostView)
if (index != -1) this.vcr.remove(index)
}
각도 v12 이하
동적 추가 및 제거 프로세스를 보여주는 데모를 만들었습니다.상위 구성 요소는 하위 구성 요소를 동적으로 생성하고 제거합니다.
데모를 보려면 클릭
상위 구성 요소
// .ts
export class ParentComponent {
@ViewChild("viewContainerRef", { read: ViewContainerRef })
VCR: ViewContainerRef;
child_unique_key: number = 0;
componentsReferences = Array<ComponentRef<ChildComponent>>()
constructor(private CFR: ComponentFactoryResolver) {}
createComponent() {
let componentFactory = this.CFR.resolveComponentFactory(ChildComponent);
let childComponentRef = this.VCR.createComponent(componentFactory);
let childComponent = childComponentRef.instance;
childComponent.unique_key = ++this.child_unique_key;
childComponent.parentRef = this;
// add reference for newly created component
this.componentsReferences.push(childComponentRef);
}
remove(key: number) {
if (this.VCR.length < 1) return;
let componentRef = this.componentsReferences.filter(
x => x.instance.unique_key == key
)[0];
let vcrIndex: number = this.VCR.indexOf(componentRef as any);
// removing component from container
this.VCR.remove(vcrIndex);
// removing component from the list
this.componentsReferences = this.componentsReferences.filter(
x => x.instance.unique_key !== key
);
}
}
// .html
<button type="button" (click)="createComponent()">
I am Parent, Create Child
</button>
<div>
<ng-template #viewContainerRef></ng-template>
</div>
하위 구성 요소
// .ts
export class ChildComponent {
public unique_key: number;
public parentRef: ParentComponent;
constructor() {
}
remove_me() {
console.log(this.unique_key)
this.parentRef.remove(this.unique_key)
}
}
// .html
<button (click)="remove_me()">I am a Child {{unique_key}}, click to Remove</button>
언급URL : https://stackoverflow.com/questions/44939878/dynamically-adding-and-removing-components-in-angular
'programing' 카테고리의 다른 글
PowerShell을 사용하여 작업 표시줄에 고정하는 방법 (0) | 2023.08.29 |
---|---|
클래스 이름으로 요소를 가져오는 방법? (0) | 2023.08.29 |
커서를 손가락 포인터로 변경 (0) | 2023.08.29 |
새로운 Promise() 생성자 내부에서 비동기/대기를 사용하는 것은 반패턴입니까? (0) | 2023.08.29 |
글로벌 임시 테이블 삭제 (0) | 2023.08.29 |