如何显示已在Angular 8中销毁的动态组件?

时间:2019-11-06 18:26:31

标签: angular angular8

我是新来的。我正在创建一个聊天应用程序,该应用程序应如下所示。

有一个用户列表,当您单击每个用户时,必须显示一个包含该用户消息的框,这将允许关闭每个框。那里一切都很好。

我的问题是,当关闭每个框时,单击相应的用户时不会再次显示。可能是由于以下事实:被点击的用户的ID存储在数组中,并且可以验证如果该ID在数组中没有显示该ID,问题是我这样做是为了防止我重复框,当它已经被显示,我不知道该怎么做。

app.component.ts

import { Component,ViewChild,ViewContainerRef,ComponentFactoryResolver,ComponentRef,OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';
import { tap } from 'rxjs/operators';
import { ConversacionComponent} from "./components/conversacion/conversacion.component";
import {ChatService} from "./services/chat.service";
import {Mensaje} from "./models/mensaje";

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css'],
    providers:[ChatService]
})
export class AppComponent implements OnDestroy {

    /*Esto se usa para poder crear el componente de las ventanas de chat dinamicamente y que cada uno pueda eliminarse*/
    @ViewChild('componentsContainer', { read: ViewContainerRef, static: false }) container: ViewContainerRef;
    private subs: Subscription[] = [];
    /****************/
    public id_usuario_destino:number;
    public personas:Array<any>;
    public id_persona:number;
    public mensajes:Mensaje[];
    public alreadyDone : number[];
    ngOnDestroy() {
        // unsubscribe from all on destroy
        this.subs.forEach(sub => sub.unsubscribe());

    }

    onClickAdd = (elemento) => {
        if(this.alreadyDone.findIndex(x => x === elemento.id) === -1)
        {
            this.alreadyDone.push(elemento.id);
            this.id_usuario_destino=elemento.id;
            this.id_persona=this.id_usuario_destino;
            this._chatService.getMessages(1,this.id_usuario_destino).subscribe(
                response=>{
                    if(response.mensajes){
                        this.mensajes=response.mensajes;
                        /*Este código es para crear las ventanas de chat dinamicas y que cada una pueda cerrarse*/
                        const factory = this.componentFactoryResolver.resolveComponentFactory(ConversacionComponent);
                        const component = this.container.createComponent(factory);
                        component.instance.destino=this.id_usuario_destino;
                        component.instance.numberCreated = this.container.length;
                        component.instance.men = this.mensajes;
                        // subscribe to component event to know when to delete
                        const selfDeleteSub = component.instance.deleteSelf
                            .pipe(tap(() => component.destroy()))
                            .subscribe();
                        // add subscription to array for clean up
                        this.subs.push(selfDeleteSub);
                        /*************************************************************************************/
                    }


                },
                error=>{
                    console.log(error);
                }
            );
        }



    }


    constructor( private componentFactoryResolver: ComponentFactoryResolver,private  _chatService:ChatService) {
        this.alreadyDone=[];
        this.personas=[
            {id:"2",
                nombre:"sergio"
            },
            {id:"3",
                nombre:"jhoyner"
            },
            {id:"4",
                nombre:"gerardo"
            },
            {id:"5",
                nombre:"fabrizio"
            }
        ]
    }



}

app.component.html

<div class="sidenav">
  <ul *ngFor="let persona of personas">
    <li><a id="{{persona.id}}"(click)="onClickAdd($event.target)">{{persona.nombre}}</a></li>
  </ul>

</div>

<ng-template #componentsContainer></ng-template>

conversacion.component.html

<button (click)="deleteSelf.emit()" style="background-color: blue; color: white">close window</button>

<p>Number at time of creation: {{ numberCreated }}</p>
<div *ngFor="let message of men">
    {{message.contenido}}--{{message.fecha}}
</div>
<hr>

conversacion.component.ts

import { Component, OnInit, Output, EventEmitter, Input } from '@angular/core';
import {Mensaje} from "../../models/mensaje";

@Component({
    selector: 'app-conversacion',
    templateUrl: './conversacion.component.html',
    styleUrls: ['./conversacion.component.css']
})
export class ConversacionComponent implements OnInit {
    @Output() deleteSelf = new EventEmitter<void>();
    @Input() numberCreated: number;
    @Input() men:Mensaje[];
    @Input() destino:number;

    constructor() { }

    ngOnInit() {
    }


}

enter image description here

1 个答案:

答案 0 :(得分:0)

在组件上为id添加一个输入,并更改delete self发射器以发射一个数字,并使用该数字来更新您的doneDone数组。

conversacion.component.html

import { Component, OnInit, Output, EventEmitter, Input } from '@angular/core';
import {Mensaje} from "../../models/mensaje";

@Component({
    selector: 'app-conversacion',
    templateUrl: './conversacion.component.html',
    styleUrls: ['./conversacion.component.css']
})
export class ConversacionComponent implements OnInit {
    @Output() deleteSelf = new EventEmitter<number>();
    @Input() numberCreated: number;
    @Input() men:Mensaje[];
    @Input() destino:number;
    @Input() id: number;

    constructor() { }

    ngOnInit() {
    }


}

然后更改在app.component.ts中查看deleteSelf发射器的位置,以执行以下操作:

component.instance.id= elemento.id;
const selfDeleteSub = component.instance.deleteSelf
                            .pipe(tap(x => {
                                this.alreadyDone = this.alreadyDone.filter(done => done != x);
                                component.destroy();}))
                            .subscribe();

conversacion.component.html:

<button (click)="deleteSelf.emit(id)" style="background-color: blue; color: white">close window</button>

<p>Number at time of creation: {{ numberCreated }}</p>
<div *ngFor="let message of men">
    {{message.contenido}}--{{message.fecha}}
</div>
<hr>