Как я могу показать динамический компонент, который уже был уничтожен в Angular 8? - PullRequest
1 голос
/ 06 ноября 2019

Я новичок с угловой. Я создаю приложение чата, которое должно работать следующим образом.

Существует список пользователей, и когда вы нажимаете на каждого из них, вы должны показать окно с сообщениями этого пользователя, это должно позволить каждому окну закрыться. ,там все нормально.

Моя проблема в том, что при закрытии каждого ящика при нажатии на соответствующего пользователя оно снова не отображается. Вероятно, это связано с тем, что идентификатор пользователя, по которому щелкнули, хранится в массиве, и подтверждается, что если этот идентификатор в массиве не показывает его, проблема заключается в том, что я делаю это, чтобы предотвратить дублированиеполе, когда оно уже отображается, и я не знаю, как еще это сделать.

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>

spokacion.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>

spokacion.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 голосов
/ 07 ноября 2019

Добавьте вход к вашему компоненту для идентификатора и измените свой собственный автоэмиттер, чтобы он испустил число, и используйте его для обновления массива ужеDone.

spokacion.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() {
    }


}

Затем измените местоположение, где вы смотрите на эмиттер deleteSelf в app.component.ts, чтобы сделать что-то вроде этого:

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

spokacion.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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...