11

I need to be able to add & remove Angular components on the fly. To do so, I'm using loadIntoLocation and dispose methods, like it:

Adding a component (from a layout manager):

this.m_loader.loadIntoLocation(MyComponent, this.m_element, 'content').then(_componentRef => {

    // Create the window and set its title:
    var component: MyComponent = (_componentRef.instance);
    component.ref = _componentRef;

    // init the component content
});

Removing a component (from the component):

this.ref.dispose();

It is nearly working: - if I add a component, and close it, it works - if I add several components, they work - but if I add component A, then remove it, then add component B, it seems like Angular gives me a reference to A, and keeps some old values (my components are draggable, and in this case the B will be created A was when I destroyed it)

Is there a way to make Angular destroy components properly, or at least to force it to create fresh ones?

Tim Autin
  • 6,043
  • 5
  • 46
  • 76
  • 2
    Can you reproduce the behavior in a plnkr? I have [this one working](http://plnkr.co/edit/z9xu3x2jVAEaoJq6TbRB?p=preview), but I'm not able (and I don't know really) how to reproduce your issue – Eric Martinez Dec 04 '15 at 17:30
  • 1
    Yep, I forked your plunker : http://plnkr.co/edit/lvQfnLfTImcRqRcxJaXU?p=preview . Click "Add new component", drag it somewhere, click "Remove", then click "Add new component" again : the component is created at the just removed one place. – Tim Autin Dec 04 '15 at 18:15
  • The problem seems to be that angular2 by default reuses the created DOM elements (took it from [this comment](https://github.com/angular/angular/issues/4795#issuecomment-151688714)). So if in your bootstrap you set `provide(APP_VIEW_POOL_CAPACITY, {useValue: 0}` it will work nicely. Here's the [plnkr updated](http://plnkr.co/edit/bqo9K5bru4CN1jZ4r9mt?p=preview). – Eric Martinez Dec 04 '15 at 21:07
  • Thanks, it solves the problem! You can add it as an answer, I'll select it. – Tim Autin Dec 07 '15 at 07:47

1 Answers1

8

As suggested by Tim,

quoting @tbosch's comment

Angular reuses previously created DOM elements by default

So to avoid this behavior, taken from the comment as well, you can use APP_VIEW_POOL_CAPACITY and assign it 0 as value.

bootstrap(MyApp, [provide(APP_VIEW_POOL_CAPACITY, {useValue: 0})])

Update

Note that since beta.1 APP_VIEW_POOL_CAPACITY was removed by #5993 and the DOM is being recreated correctly.

Eric Martinez
  • 31,277
  • 9
  • 92
  • 91