5

Hie...I found a post regarding Adding and removing of components using Dynamic Component Loader and Dispose Method. I want to destroy the components created all at once. I have the plunker demo and the source where i found the demo Angular 2 - Adding / Removing components on the fly ... I know that i want to store all the componentref in an array then iterate them and dispose it...But i am not able to make it work...Please help me how to destroy all the components.

     remove() {
    this._ref.dispose();
  }

this is how i destroy a single component...How to destroy all at once?

Community
  • 1
  • 1
abhilash reddy
  • 1,546
  • 8
  • 31
  • 53

1 Answers1

6

The simplest way to do what you're asking how to do is to keep track of the ComponentRefs as you add them and call dispose() on each in a loop when you want to remove them. See updated plunk

export class App {
  ...
  private _children:ComponentRef[] = [];

  add() {
    this._dcl.loadIntoLocation(DynamicCmp, this._e, 'location').then((ref) => {
      ...
      this._children.push(ref);
    });
  }

  removeall(){
    this._children.forEach(cmp=>cmp.dispose());
    this._children = []; // not even necessary to get the components off the screen
  }
}

If for some reason it's super important that you only call dispose() once, you could create a "container", add your DynamicComponents as children of that, and then dispose the container, automatically disposing its children.

Having said that, I can't imagine a situation where I'd prefer doing that over adding the four lines of code it takes to implement what I outlined above...

Having said all that: If there's a way to use data binding to do what you're trying to do, you should favor that over falling back on DynamicComponentLoader unless you have a damn good reason not to.

I'll be the first to tell you there are use-cases where DCL is needed, but in my (albeit brief) experience, for every five I initially thought needed it, I came up with data-binding solutions for at least three after giving it a little thought.

In this case, doing that was trivial - see other updated plunk:

@Component({
  selector: 'my-app',
  template : `
    <button (click)="add()">Add new component</button>
    <button (click)="removeAll()">Remove All</button>
    <template ngFor #child [ngForOf]="children">
       <div [dynamicCmp]="child"></div>
    </template>
  `,
  directives:[DynamicCmp]
})
export class App {
  children:number[] = [];

  add() {
    this.children.push(this.children.length+1);
  }

  removeAll(){
    this.children = [];
  }

}
drew moore
  • 31,565
  • 17
  • 75
  • 112
  • Thanks for your guidance brother – abhilash reddy Jan 04 '16 at 10:28
  • 7
    **update** `.dispose()` is `destroy()` **since beta.16** – Günter Zöchbauer Apr 26 '16 at 13:42
  • well that was quick, @GünterZöchbauer :-P I started to edit my answer to reflect this, but I'd have to edit the question too. I haven't looked into this API change yet - would changing all references to `destroy()` in the question and answer alter the semantics of either? – drew moore Apr 27 '16 at 03:29
  • Actually no, `loadIntoLocation` was removed and `loadNextToLocation` takes a `ViewContainerRef` instead of an `ElementRef`. I don't know if the CHANGELOG.md was already updated. You can search my answers (I'm on the phone). I updated a few related answers yesterday. – Günter Zöchbauer Apr 27 '16 at 04:32
  • http://stackoverflow.com/a/35171088/217408, https://github.com/angular/angular/pull/8241/files – Günter Zöchbauer Apr 27 '16 at 05:45