2015-11-03 12 views
14

Sto sviluppando un app Angular2, e ho dovuto affrontare un problema:Angular2: i dati a due vie che vincolano componente inserito dinamicamente utilizzando DynamicComponentLoader

Ho una serie di oggetti diversi che possono essere selezionati tramite interfaccia utente. Ognuno di questi oggetti ha una serie di opzioni (diverse per oggetti diversi) che possono essere modificate usando l'interfaccia utente. Ora, sto usando DynamicComponentLoader per inserire un componente specifico per l'oggetto attualmente selezionato, in modo che possa gestire correttamente le sue opzioni. Il problema è che non so come associare i dati dell'oggetto attualmente selezionato a un componente di opzioni inserito dinamicamente.

@Component({ 
    selector: 'dynamic', 
    template: `<div>Options:</div> 
      <div>Property1: <input type="number" /></div> 
      <div>Property2: <input type="text" /></div>` 
    // template: `<div>Options:</div> 
    //   <div>Property1: <input type="number" [(ng-model)]="currentSelection.property1" /></div> 
    //   <div>Property2: <input type="text" [(ng-model)]="currentSelection.property1" /></div>` 
}) 
class DynamicComponent { 

} 


@Component({ 
    selector: 'my-app', 
    template: ` 
    <div> 
     <h2>Selected: {{currentSelection.name}}!</h2> 
     <div #container></div> 
    </div> 
    ` 
}) 
class App { 
    currentSelection = {name: 'Selection1', property1: 10, property2: 'test'}; 

    constructor(private loader: DynamicComponentLoader, private elementRef: ElementRef) { 
    loader.loadIntoLocation(DynamicComponent, elementRef, 'container'); 
    } 
} 

Here è un plunker per aiutarvi a capire la mia domanda:

+1

l'unico esempio c'è in giro è questo https://github.com/angular/angular/blob/1aeafd31bd440a4997362e66738926387940fc1e/modules/angular2_material/src/components/dialog/dialog.ts –

risposta

4

Con angular2 e Rxjs, "Observables" sono quasi sempre la risposta.

se ho capito bene il problema, è necessario per rendere il vostro DynamicComponent un "Observer" e il contenitore "un Observable o meglio ancora un Subject (Nel caso in cui il vostro contenitore ha bisogno di iscriversi ad un altro osservabile per ricevere le selezioni da)". Quindi, dopo aver caricato il tuo componente dinamico, iscriverlo al tuo contenitore.

Ogni volta che la selezione cambia sul contenitore, si preme la nuova selezione ai propri abbonati. In questo modo, puoi caricare più componenti dinamici e tutti riceveranno le tue spinte.

del contenitore:

class App { 
    currentSelection = {}; 
    selections = [ 
    {name: 'Selection1', property1: 10, property2: 'test'}, 
    {name: 'Selection2', property1: 20, property2: 'test2'} 
    ]; 
    subject:Subject<any> = new Subject(); 

    constructor(private loader: DynamicComponentLoader, private elementRef: ElementRef) { 
    } 

    ngOnInit(){ 
    this.loader.loadIntoLocation(DynamicComponent, this.elementRef, 'container', this.injector) 
    .then(compRef =>this.subject.subscribe(compRef.instance)); 
    // subscribe after loading the dynamicComponent 
    } 

    // set the new selection and push it to subscribers 
    changeSelection(newSelection){ 
    this.currentSelection = newSelection; 
    this.subject.next(this.currentSelection); 
    } 
} 

The Observer:

class DynamicComponent implements Observer{ 
    public currentSelection = {}; 

    next(newSelection){ 
    this.currentSelection = newSelection; 
    } 
} 

Ecco la vostra plunker lavorativi dopo le mie modifiche, "a condizione ho cambiato le importazioni per il nuovo beta.6 angolare"

So che questa è una domanda piuttosto vecchia. Ma spero che qualcuno possa beneficiare di questa risposta.

2

Ecco cosa è possibile fare, spostare il codice da constructor a ngOnInit e utilizzare le promesse per l'assegnazione del valore dinamico.

ngOnInit(){ 
    this.dynamicComponentLoader.loadIntoLocation(DynamicComponent, this.elementRef,'container').then((component)=>{ 
     component.instance.currentSelection = currentSelection; 
    }); 
} 
Problemi correlati