Как избежать дублирования при создании динамического компонента с одинаковой угловой информацией8 - PullRequest
0 голосов
/ 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 {

    @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[];

    ngOnDestroy() {
        // unsubscribe from all on destroy
        this.subs.forEach(sub => sub.unsubscribe());

    }

    onClickAdd = (elemento) => {
        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;

                    const factory = this.componentFactoryResolver.resolveComponentFactory(ConversacionComponent);
                    const component = this.container.createComponent(factory);
                    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.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.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: EventEmitter<void> = new EventEmitter<void>();
    @Input() numberCreated: number;
    @Input() men:Mensaje[];

    constructor() { }

    ngOnInit() {
    }

}

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>

enter image description here

1 Ответ

1 голос
/ 06 ноября 2019

Вы можете просто отслеживать массив идентификаторов, которые уже были добавлены, и в своем методе onClickAdd проверить, есть ли идентификатор в массиве, и если это так, не выполняйте остальную часть вашего метода. Нечто похожее на приведенное ниже с переменной 'readyDone':

export class AppComponent implements OnDestroy {

    @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(alreadyDone.findIndex(x => x === elemento.id) === -1)
        {
            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;

                        const factory = this.componentFactoryResolver.resolveComponentFactory(ConversacionComponent);
                        const component = this.container.createComponent(factory);
                        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.personas=[
            {id:"2",
                nombre:"sergio"
            },
            {id:"3",
                nombre:"jhoyner"
            },
            {id:"4",
                nombre:"gerardo"
            },
            {id:"5",
                nombre:"fabrizio"
            }
        ]
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...