简体   繁体   English

Angular-动态销毁组件* ngIf和ComponentRef

[英]Angular - dynamically destroying a component, *ngIf and ComponentRef

I'm making a pop-up component that I want to use in several of my other components, so I made a popup.service that enable the component to be loaded through *ngIf inside other components. 我正在制作一个要在其他几个组件中使用的弹出组件,所以我制作了一个popup.service,使该组件可以通过* ngIf加载到其他组件中。 This is creating a problem for me since the PopupComponent is a separate entity and I'm unsure how to pass data from the child component(PopupComponent) to its respective parents. 这对我来说是一个问题,因为PopupComponent是一个单独的实体,并且我不确定如何将数据从子组件(PopupComponent)传递到其相应的父组件。

Atm the loading looks like this in ParentComponent.ts: Atm在ParentComponent.ts中的加载如下所示:

public openPopup(order_id: string, invoice_id: string): void{
      this.load_popup=this.popupService.openPopup(order_id, "selected_order", invoice_id, "selected_invoice");
  }

And ParentComponent.html: 和ParentComponent.html:

<app-popup *ngIf="load_popup"></app-popup>

And it loads like a charm, the problem is in closing it. 它的加载就像一种魅力,问题在于关闭它。 The close button is located on the PopupComponent, is there an efficient way to have the Child Component (PopupComponent) to affect a variable in the Parent Component ie. 关闭按钮位于PopupComponent上,是使子组件(PopupComponent)影响父组件中变量的有效方法。 ParentComponent.load_popup=false ? ParentComponent.load_popup=false

My other thought was dynamically loading the component, however I have no idea on how to do that. 我的另一个想法是动态加载该组件,但是我不知道该怎么做。 I was fidgeting around with using the PopupService and putting something like this in it: 我对使用PopupService感到不安,并在其中添加了以下内容:

import { Injectable, ComponentRef } from '@angular/core';

import {PopupComponent} from '../popup/popup.component';

@Injectable({
  providedIn: 'root'
})
export class PopupService {
  popup_ref: ComponentRef<PopupComponent>

  constructor(
  ) { }

  //Implemented in orderoverviewcomponent, invoicecomponent, and placeordercomponent
  public openPopup(id1:string, storage_label1:string, id2:string, storage_label2:string): Boolean{
    if (id1){
      localStorage.setItem(storage_label1, JSON.stringify(id1));
    }
    if (id2){
      localStorage.setItem(storage_label2, JSON.stringify(id2));
    }
    this.popup_ref.initiate(); //this line is a made up example of loading the component
    return true;
  }
  public closePopup(storage_label1: string, storage_label2:string): Boolean{
    if(storage_label1){
      localStorage.removeItem(storage_label1);
    }
    if(storage_label2){
      localStorage.removeItem(storage_label2);
    }
    this.popup_ref.destroy();
    return false;
  }
}

Where this.popup_ref.destroy(); 其中this.popup_ref.destroy(); would ideally destroy PopupComponent, but when I did that I got a "cannot read property of undefined" on the popup_ref, I'm having trouble declaring it, the syntax seems a bit tricky. 理想情况下会破坏PopupComponent,但是当我这样做时,我在popup_ref上得到了“无法读取未定义的属性”,我在声明它时遇到了麻烦,语法似乎有些棘手。

The problem also remains that i need a function to load the component, the opposite of .destroy(), if this is possible I would much prefer it over loading and destroying with *ngIf. 问题还在于,我需要一个函数来加载组件,与.destroy()相反,如果可能的话,我宁愿使用* ngIf加载和销毁它。

Edit: Partially solved it by just using a boolean in the service as the trigger for *ngIf, is there a way to do a function load and destroy on a component still? 编辑:仅通过在服务中使用布尔值作为* ngIf的触发器来部分解决它,是否有办法在组件上进行函数加载和销毁?

You can bind an EventEmitter() to your component to invoke a function in the parent component. 您可以将EventEmitter()绑定到您的组件,以调用父组件中的函数。

<app-popup [onClose]="load_popup = false" *ngIf="load_popup"></app-popup>

Then inside of your app-popup component: 然后在您的应用程序弹出组件内部:

@Output onClose = new EventEmitter();

public closePopup(/* code emitted for brevity */) {
    /* code emitted for brevity */
    this.onClose.emit(); //Call the parent function (in this case: 'load_popup = false')
}

It's important to know that you can pass entire functions to the bound function, and you can even pass variables back to the parent from the child: 重要的是要知道您可以将整个函数传递给绑定函数,甚至可以将变量从子级传递回父级:

[onClose]="myFunction($event)"
this.onClose.emit(DATA HERE);

As an aside, since you're using Angular; 顺便说一句,由于您使用的是Angular; I would suggest looking into using Modals for popup dialogue boxes. 我建议考虑使用Modals弹出对话框。 You can see a good example here: 您可以在这里看到一个很好的例子:

https://ng-bootstrap.github.io/#/components/modal/examples https://ng-bootstrap.github.io/#/components/modal/examples

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM