Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Destroy component itself #55511

Closed
cl-yklilich opened this issue Apr 24, 2024 · 10 comments
Closed

Destroy component itself #55511

cl-yklilich opened this issue Apr 24, 2024 · 10 comments
Labels
area: core Issues related to the framework runtime
Milestone

Comments

@cl-yklilich
Copy link

cl-yklilich commented Apr 24, 2024

Which @angular/* package(s) are relevant/related to the feature request?

core

Description

I have a component that has a remove button, the remove button simply needs to destroy component instance, but I couldn't figure out a simple straightforward way to do it.

Proposed solution

it would be nicer if we have some sort of function to do it, since I noticed this feature has been already requested 18673, the suggestion provided on this comment actually doesn't work as I imagine it.
I propose if there is a simple and easy way to inject a destroy reference to component and destroy the component.

Alternatives considered

(Nothing to add)

@JoostK
Copy link
Member

JoostK commented Apr 24, 2024

I would be nicer if we have some sort of function to do it, since I noticed this feature has been already requested #18673, the suggestion provided on this #18673 (comment) actually doesn't work as I imagine it.

As mentioned, it's important for the component to be hosted within its own embedded view, as otherwise you're killing a component that is still being attached from its parent view, breaking the parent view in the process (and there wouldn't be a way for the parent view to reinstantiate the component).

@pkozlowski-opensource
Copy link
Member

To add to @JoostK comment - it is really about the mental model of Angular that:

  • requires a host element to attach directives / components;
  • assumes that a view is a fixed structure (in terms of DOM nodes and directives / components).

If we take those two very fundamental decisions into account there is no real concept of destroying "self":

  • a component doesn't own its host node so it couldn't be removed from the DOM anyway;
  • a component instance can be referenced by other components / directives (ex.: local references, DI, queries) and others might hold onto those instances - what should happen if / when we destroy such component?

@JoostK
Copy link
Member

JoostK commented Apr 24, 2024

You can achieve it using e.g. the pattern implemented by DialogRef, see #18673 (comment). Then the component is indeed destroyed from the parent, but the DialogRef service can be requested by descendant components to cause their parent to close.

@cl-yklilich
Copy link
Author

So in order to destroy a component, should I destroy it from the parent component programmatically ?
because I found some resources says in order to destroy a component, it needs to be created using ViewContainerRef in order to destroy it when needed.
@JoostK , @pkozlowski-opensource

@ev45ive
Copy link

ev45ive commented Apr 24, 2024

@cl-yklilich Use top-down flow control - parents control children, not other way around
( unless you want your kids to become despots and tyrants when they grow up ;-) )

Parent component creates your component, updates inputs, and destroys / re-creates it.

So in parent component should have isOpen boolean flag and create child like this:

@if( isChildOpen == true ) { <app-child-component (close)="isChildOpen = false"  /> }

or if using older version:

 <app-child-component (close)="isOpen = false" *ngIf="isChildOpen == true"  /> }

then the child can emit close signal and ask parent politely to destroy this child.:
from child:

class ChildComponent{

   @Output() close = new EventEmitter()   // or // close = output();
   
   closeBtnClick(){ 
        this.close.emit(true) 
   }
}

@thePunderWoman thePunderWoman added the area: core Issues related to the framework runtime label Apr 30, 2024
@ngbot ngbot bot added this to the needsTriage milestone Apr 30, 2024
@yassine-klilich
Copy link

yassine-klilich commented May 1, 2024

@JoostK @pkozlowski-opensource this is me from another account.

I have been trying to find a solution to destroy child component from the parent component by removing item from an array, and I found something weird happening, here is a demo

If you noticed I'm logging the ID for the destroyed child component, when I click delete for child 300 to be deleted, in fact it gets deleted, but the OnDestroy lifecycle doesn't trigger, instead the child 400 who actually triggers the OnDestroy event.

any idea why this is happening, I start feeling it is like a bug on angular.

@JoostK
Copy link
Member

JoostK commented May 1, 2024

That's because you track by index, so once there is one fewer component in the array all components besides the last is matched to an existing component, and only the last is removed

@JoostK
Copy link
Member

JoostK commented May 1, 2024

So in your StackBlitz you'd want to change track $index to track item.id

@yassine-klilich
Copy link

oooh I really missed that part, thanks a lot @JoostK , really appreciate your effort <3.

@JeanMeche
Copy link
Member

@yassine-klilich Feel free to close this issue if the solution suits you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: core Issues related to the framework runtime
Projects
None yet
Development

No branches or pull requests

7 participants