Ya no busques más por todo internet porque has llegado al lugar justo, poseemos la solución que buscas sin liarte.
Solución:
Lo que está tratando de lograr se puede hacer creando componentes dinámicamente usando el ComponentFactoryResolver
y luego inyectarlos en un ViewContainerRef
. Una forma de hacer esto dinámicamente es pasar la clase del componente como un argumento de su función que creará e inyectará el componente.
Vea el ejemplo a continuación:
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: `
`
)
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)
// 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)
// 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);
Notas:
-
Si desea facilitar la eliminación de los componentes más adelante, puede realizar un seguimiento de ellos en una variable local, consulte
this.components
. Alternativamente, puede recorrer todos los elementos dentro delViewContainerRef
. -
Tiene que registrar su componente como componente de entrada. En la definición de su módulo, registre su componente como componente de entrada (
entryComponents: [DraggableComponent]
).
Ejemplo de ejecución: https://plnkr.co/edit/mrXtE1ICw5yeIUke7wl5
Para más información: https://angular.io/guide/dynamic-component-loader
Creé una demostración para mostrar el proceso dinámico de agregar y quitar. El componente principal crea los componentes secundarios dinámicamente y los elimina.
Haga clic para demostración
Componente principal
// .ts
export class ParentComponent
@ViewChild("viewContainerRef", read: ViewContainerRef )
VCR: ViewContainerRef;
child_unique_key: number = 0;
componentsReferences = Array>()
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
Componente secundario
// .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
Comentarios y puntuaciones
Tienes la opción de añadir valor a nuestro contenido informacional tributando tu veteranía en las anotaciones.