2016-03-26 10 views
9

Esame della risposta di Eric Martinez da Angular 2 - Adding/Removing components on the fly, Voglio limitare la quantità di componenti creati. E poi dopo aver eliminato un componente, sto cercando di emettere quell'evento al genitore in modo che il genitore conosca il numero di componenti attualmente creati.Come posso utilizzare un emettitore di eventi su un componente aggiunto dinamicamente?

In questo Plunker, limito il numero di componenti per 4, e quindi sto tentando di emettere un evento per ridurre tale conteggio indietro. L'evento non sta emettendo. Come si emette un evento da un componente aggiunto dinamicamente?

// dynamic component 
@Component({ 
    selector : 'dynamic', 
    template : ` 
    <div> 
     Component number {{_idx}} <button (click)="remove()">Remove</button> 
    </div>` 
}) 
class DynamicCmp { 
    _ref: ComponentRef; 
    _idx: number; 
    @Output lowerIndex = new EventEmitter<any>(); 
    remove() { 
     this._ref.dispose(); 
     this.lowerIndex.emit(true); 
    } 
} 

// Parent container component  
@Component({ 
    selector: 'my-app', 
    template : ` 
     <button (click)="add()">Add new component</button> 
     <div #location (lowerIndex)="lowerIndex();"></div> 
    ` 
}) 
export class App { 
    idx: number = 0; 
    constructor(private _dcl: DynamicComponentLoader, private _e: ElementRef) {} 

    lowerIndex() { 
     this.idx--; 
     console.log("subtracted"); 
    } 

    add() { 
     if (this.idx < 4) { 
      this._dcl.loadIntoLocation(DynamicCmp, this._e, 'location').then((ref) => { 
      ref.instance._ref = ref; 
      ref.instance._idx = this.idx++; 
      }); 

      console.log("added") 
     } 
    } 
} 

ho postato i componenti in qui perché StackOverflow richiede il codice scritto con i link plunker. Il codice è esattamente lo stesso visto in plunker

risposta

19

Il problema qui è che i componenti caricati dinamicamente non hanno una relazione genitore/figlio con i componenti in cui sono caricati. Ecco perché accedere alle proprietà dal componente caricato dinamicamente devi usare ref.instance.property. Il componente non viene compilato insieme al genitore, pertanto il genitore non sa nulla del componente adottivo.

Ora, detto questo, quello che puoi fare è creare una proprietà a cui puoi iscriverti e I wouldn't use an EventEmitter per quello.

La mia soluzione sarebbe quella di utilizzare un oggetto invece (come sto facendo in un piccolo progetto del mio).

Il componente dinamica sarebbe simile a questa

class DynamicCmp { 

    // Subject instead of an EventEmitter 
    lowerIndex: Subject<boolean> = new Subject(); 

    remove() { 
     // We send true, although in the example is not being used 
     this.lowerIndex.next(true); 

     // Remove the component from the view 
     this._ref.dispose(); 
    } 
} 

Il componente in cui si sta caricando la componente dinamica

template : '<div #location></div>'; // Note that I removed (lowerIndex)="..." 
this._dcl.loadIntoLocation(DynamicCmp, this._e, 'location').then((ref) => { 
    //... 

    // Subscribe to the Subject property 
    ref.instance.lowerIndex.subscribe(v => { 
     this.idx--; 
     console.log("subtracted"); 
    }); 
}); 

Ecco la tua plnkr lavoro e aggiornato per beta.12.

+1

Fantastico! Grazie per il tuo aiuto Eric :) –

+1

@philipyoo sei il benvenuto! –

+4

* componente Foster *: molto adatto. – drewmoore

Problemi correlati