【问题标题】:how to hide dynamically created Component in Angular 6如何在Angular 6中隐藏动态创建的组件
【发布时间】:2019-06-25 20:29:34
【问题描述】:

我在材料步进器上使用 ComponentFactory 动态加载组件,我想隐藏前一个组件并在每一步加载新组件。

当前代码-目前我的组件正在加载每个步骤,但它正在破坏以前的组件并加载新的组件广告我不想破坏以前的组件。请在下面找到我的代码

ComponentLoad 方法:-

 loadComponent(CurrentindexValue: any) {


        this.currentAdIndex = CurrentindexValue;
        this.currentAdIndex = (this.currentAdIndex) % this.wizardValue.component.length;
        let adComponentItem = this.wizardValue.component[this.currentAdIndex];
        console.log(adComponentItem);
        const factories = Array.from(this.componentFactoryResolver['_factories'].keys());
        var factoryClass = <Type<any>>factories.find((x: any) => x.name === adComponentItem);

        let componentFactory = this.componentFactoryResolver.resolveComponentFactory(factoryClass);
       
        let viewContainerRef = this.adhost;
        viewContainerRef.clear();
        let componentRef = this.adhost.createComponent(componentFactory);



        this.interval = componentRef
    }

enter image description here

import { Component, ViewChild, ViewChildren, Input, OnInit, ComponentFactoryResolver, OnDestroy, ViewContainerRef, AfterViewInit, QueryList, HostBinding } from '@angular/core';
import { FormGroup, Validators, FormBuilder } from '@angular/forms';
import { MatStepper } from '@angular/material';
import { AdComponentItem } from 'src/app/shared/addcomponent';
import { ActivatedRoute, Router } from '@angular/router';
import { NewWizardService } from 'src/app/shared/newwizard.service';
import { Type } from '@angular/core';


export class Wizard {
    id: number;
    Action: string;
    Title: string[];
    component: string[];

}
interface Step {
    label: string;
    id: any;
    componentName: any;
}

@Component({
    selector: 'new-wizard',
    templateUrl: './newwizard.component.html',
    styleUrls: ['./newwizard.component.css'],
})
export class CreateDatasourceWizardComponent implements OnInit, OnDestroy, AfterViewInit {
    @Input() ads: AdComponentItem[];
    private isButtonVisible = false;
    wizards: Wizard[];
    wizardcountry: string[];
    wizardcomponent: Wizard[];
    wizardValue: Wizard;
    currentIndex: any;
    cmpRef = [];
    currentAdIndex = -1;
    querypvalue: any;
    show: boolean;
    myvar: any;
    @ViewChild('stepper') stepper: MatStepper;
    @ViewChild('adhost', { read: ViewContainerRef }) adhost: ViewContainerRef;
    @HostBinding('hidden')
    isHidden: boolean = false;
    interval: any;


    constructor(private componentFactoryResolver: ComponentFactoryResolver,
        private route: ActivatedRoute, private _router: Router, private wizardData: NewWizardService) {
        this.wizards = [];

    }
    ngOnInit() {

        this.getWizardData();
        this.currentIndex = this.stepper.selectedIndex;

    }

    ngOnDestroy() {
        
        // this.interval.destroy();
    }
    ngAfterViewInit() {

        this.loadComponent(this.stepper.selectedIndex);
       

    }

    getWizardData(): void {

        this.wizardData.getData().then((result) => {
            this.wizards = result;

            this.route.queryParams.subscribe(params => {
                this.querypvalue = params['action'];
                this.setupWizard(this.querypvalue);
            });

        })
    }

    setupWizard(value: string): void {

        this.wizardValue = this.wizards.find(c => c.Action == value);
        console.log(this.wizardValue);

    }

    loadComponent(CurrentindexValue: any) {


        this.currentAdIndex = CurrentindexValue;
        this.currentAdIndex = (this.currentAdIndex) % this.wizardValue.component.length;
        let adComponentItem = this.wizardValue.component[this.currentAdIndex];
        console.log(adComponentItem);
        const factories = Array.from(this.componentFactoryResolver['_factories'].keys());
        var factoryClass = <Type<any>>factories.find((x: any) => x.name === adComponentItem);

        let componentFactory = this.componentFactoryResolver.resolveComponentFactory(factoryClass);
        let viewContainerRef = this.adhost;
        viewContainerRef.clear();
        let componentRef = this.adhost.createComponent(componentFactory);
        this.interval = componentRef
    }
  

    goBack(stepper: MatStepper) {
        stepper.previous();

        console.log(stepper.selectedIndex);
        this.currentIndex = stepper.selectedIndex
        this.loadComponent(stepper.selectedIndex);
        //this.loadPreviousComponent(stepper.selectedIndex);

    }
    goForward(stepper: MatStepper) {
        stepper.next();

        this.loadComponent(stepper.selectedIndex);

    }
}
<div class="ui-widget-header">
        <span class="field-caption" style="margin-left: 15px;">{{wizardValue.Action}}</span>
    </div>
<div class="container-fluid">
    
<div class="row">
<div class="col-md-12">
    <mat-horizontal-stepper [@.disabled]="true" [linear]="true" #stepper class="stepper-class">
        <mat-step *ngFor="let i of wizardValue.Title">
            <ng-template matStepLabel>{{i}}
            </ng-template>
           
        </mat-step>
       
    </mat-horizontal-stepper>
</div>
</div>
<div class="row">
    <div class="col-md-12">
<mat-card>
  <div *ngFor="let i of wizardValue.component let test = index " [id]="i" >
        <!-- <span (onCreate)="onCreate(test)"></span> -->
        
 <ng-template #adhost></ng-template>
 </div>
  
</mat-card>
</div>
</div>
<div class="row float-right">
<div class="col-md-12 stepper-button">
        <button class="btn btn-primary back-button"  (click)="goBack(stepper)" type="button" [disabled]="stepper.selectedIndex===0">Previous</button>
        <button class="btn btn-primary Next-button" (click)="goForward(stepper)" type="button" [disabled]="stepper.selectedIndex===stepper._steps.length-1">Next</button>
        
    </div>

    
</div>
</div>
步进图像

【问题讨论】:

  • 我认为你可以用 *ngIf 轻松创建
  • 如何使用 *ng 创建步骤标题和组件名称的 json 对象
  • 您可以直接在 div 标签中应用 *ngIf,如果该语句存在,那么它将显示我刚刚为您做了一个简单的示例。 stackblitz.com/edit/angular-ngif-example1

标签: angular typescript


【解决方案1】:

我认为您应该将实例保存在公共变量中并在适当的条件下销毁它:

public dynamicComponent: any;

loadComponent(CurrentindexValue: any) {
    ...
    this.dynamicComponent = this.adhost.createComponent(componentFactory);
    ...
}

现在您可以在方法中销毁组件。

destroyIt(){
    this.dynamicComponent.destory(); 
}

现在您只需要随时调用此方法即可。

【讨论】:

  • 但我不想销毁它我想隐藏组件并在最后一步提交按钮上销毁它
【解决方案2】:

您只需要创建一个输入并在您的组件模板中将其用作 *ngIf 语句

public dynamicComponent: any;

loadComponent(CurrentindexValue: any) {
    ...
    this.dynamicComponent = this.adhost.createComponent(componentFactory);
    this.dynamicComponent.hided.subscribe(t => {
        this.hided.emit(true);
        // this is for recalling
    })
} 

hideIt(){
    this.dynamicComponent.hide = true; 
}

在您的组件中:

@Input('hide')
set hide(value: boolean) {
this.emidHided();
}
@Output() hided: EventEmitter<>;


public emitHided() {
    this.hided.emit()
}

语法需要一些修正

【讨论】:

  • 感谢您的回复,但是当我使用它时,我收到错误找不到未定义的 createComponent。您能否在我的代码中添加修改。
猜你喜欢
  • 2022-07-21
  • 1970-01-01
  • 1970-01-01
  • 2017-09-10
  • 1970-01-01
  • 2021-03-29
  • 2019-09-02
  • 2017-07-07
  • 2019-01-25
相关资源
最近更新 更多