2015-10-01 15 views
6

sto usando alfa angular2 37.componenti Generazione bambino in angular2 con NgFor non funziona

ho definito un componente <map> e un <marker> componente (figlio di <map>). Il componente <map> ha un membro dati matrice che contiene un elenco di coordinate marker. La vista <map> dovrebbe visualizzare tutti i marcatori nella matrice

Quando si definisce la vista <map> come segue (componenti dell'annuncio esplicitamente per tutti i membri dell'array):

@View({ 
    template:` 
    <marker [model]="markers[0]"></marker> 
    <marker [model]="markers[1]"></marker> 
    `, 
    directives:[Marker] 
}) 

I componenti <marker> vengono aggiornati ogni volta corrispondenti modifiche utente matrice. Questo è il comportamento desiderato.

Quando si definisce la visualizzazione <map> (usando NgFor) come segue: viene creato

@View({ 
    template: '<marker *ng-for="#m of markers" [model]="m"></marker>', 
    directives:[Marker,NgFor] 
}) 

un nuovo marcatore quando i membri dell'array cambiano, il che non è desiderabile.

Aghi per dire che mi piacerebbe utilizzare il metodo NgFor.

Non ho idea di cosa stia succedendo. Come posso utilizzare NgFor ma evitare che vengano create nuove istanze <marker> ogni volta che i singoli marcatori vengono aggiornati?

+0

qualche informazione in più: quando si crea un '' componente, in realtà crea pennarello su una mappa illustrativo. Quando il componente è aggiornato, l'indicatore sulla mappa dovrebbe aggiornarsi –

risposta

0

provare questo

@View({ 
template:"<marker *ng-for="#m of markers" [model]="m">{{m}}</marker>", 
directives:[Marker,NgFor] 
}) 
+0

Grazie per l'input, ma questo produce gli stessi risultati. Ad ogni cambio di '# m', viene creato un nuovo marcatore invece di essere aggiornato. –

3

Split lista ngFor itera dall'esercizio dati del modello.

Questo è il codice Dart, ma non dovrebbe essere difficile da tradurre in TS

import 'dart:math' show Random; 
import 'package:angular2/angular2.dart'; 

@Component(
    selector: 'app-element', 
    template: ''' 
<h3>app-element</h3> 
<map></map> 
    ''', 
    directives: const [MapComponent]) 
class AppElement {} 
@Component(selector: 'map', 
    template: ''' 
<button (click)="changeValue()">Change value</button> 
<marker *ngFor="let m of markersIndexes" [model]="markers[m]"></marker> 
<!-- use `markers[m]` to assign a model but `markersIndexes` for `*ng-for` --> 
''', 
    directives: const [MarkerComponent, NgFor]) 
class MapComponent { 
    MapComponent() { 
    markers = <Marker>[ 
     new Marker('m0', 0), 
     new Marker('m1', 1), 
     new Marker('m2', 2), 
     new Marker('m3', 3) 
    ]; 
    markersIndexes = new List<int>.generate(markers.length, (int index) => index); 
    } 
    List<Marker> markers; // model to pass to <marker> 
    List<int> markersIndexes; // indexes used by *ng-for 
    // when markers are added or removed markersIndexes need to by updated of course 

    // Update random marker item with random position value  
    Random _rnd = new Random(); 
    void changeValue() { 
    int idx = _rnd.nextInt(3); 
    markers[idx].position = _rnd.nextInt(100); 
    } 
} 
@Component(
    selector: 'marker', 
    template: ''' 
<h3>marker</h3> 
<div>name: {{model.name}} pos: {{model.position}} created: {{createdAt}}</div> 
''', 
    styles: const [ 
     ''' 
:host { 
    display: block; 
    border: 1px solid green; 
} 
''' 
    ]) 
class MarkerComponent implements OnInit { 
    @Input() Marker model; 
    String createdAt; 

    MarkerComponent() { 
    createdAt = new DateTime.now().toString(); 
    } 
    void ngOnInit() { 
    print(model); 
    } 
} 
// Marker model 
class Marker { 
    String name; 
    int position; 

    Marker(this.name, this.position); 

    @override 
    String toString() => 'Marker: $name - $position'; 
} 
+0

Funziona davvero come previsto. È un peccato, però, che questo uso esplicito di indici sia necessario per questo caso d'uso. Controllerò anche l'altra risposta prima di concedere il premio finale –

+1

Inoltre mi aspetto che anche le seguenti funzioni funzionino, ma questo non è il caso: ' ' –

+1

E in che modo questa scala quando la matrice' marcatori' cambia in modo dinamico la lunghezza? I corrispondenti 'markersIndexes' dovrebbero essere ricalcolati in ogni momento? –

0

ho visto che si utilizza la versione alpha37 che rimane una versione alpha e puoi avere alcuni bug ... Ho fatto alcuni test usando la versione beta0 e sembra funzionare come previsto. Quindi ti consiglierei di aggiornare a questa versione ...Ci aspettiamo che le versioni beta di essere più stabile ;-)

Ecco il codice che ho usato per il mio test fatti:

  • componente principale dei dati

    @Component({ 
        selector: 'first-app', 
        template: ` 
         <map></map> 
        `, 
        directives: [ MapComponent ] 
    }) 
    export class AppComponent { 
    } 
    
  • Marker oggetto

    class Marker { 
        name: string; 
        position: int; 
    
        constructor(name, position) { 
        this.name = name; 
        this.position = position; 
        } 
    } 
    
  • Marker componente

    @Component({ 
        selector: 'marker', 
        template:` 
        <div class="marker">Marker {{model.name}} <button (click)="update()">Update</button></div> 
        `, 
        directives:[MarkerComponent] 
    }) 
    export class MarkerComponent implements OnInit { 
        @Input() model: Marker; 
    
        constructor() { 
    
        } 
    
        ngOnInit() { 
        } 
    
        update() { 
        this.model.name = this.model.name + 'a'; 
        } 
    } 
    
  • Map componente

    @Component({ 
        selector: 'map', 
        template:` 
        <marker *ngFor="#m of markers" [model]="m"></marker> 
        <button (click)="update()">Update</button> 
        `, 
        directives:[MarkerComponent] 
    }) 
    export class MapComponent { 
        constructor() { 
        this.markers = [ 
         new Marker('m0', 0), 
         new Marker('m1', 1), 
         new Marker('m2', 2), 
         new Marker('m3', 3) 
        ]; 
        } 
    
        update() { 
        this.markers[1].name = 'm1a'; 
        } 
    } 
    

Quando clicco su entrambi i pulsanti di aggiornamento, il nome del secondo marcatore viene aggiornato nella vista e non viene visualizzato alcun ulteriore elemento <marker>.

Modifica

Potrebbe essere il modo in cui si aggiorna l'elemento della lista. Lo sostituisci con una nuova istanza o aggiorni il valore di un attributo per un'istanza esistente nell'elenco? Nel primo caso, penso che si potrebbe aggiungere un nuovo elemento nell'elenco.

update() { 
    this.markers[1]= new Marker('m1a', 1); 
} 

Dopo aver eseguito alcuni test, questo approccio funziona anche. Nessun elemento aggiunto nell'elenco.

Spero che ti aiuta, Thierry

+0

Grazie per l'input. Prima di iniziare il bounty, ho aggiornato all'ultima beta. Tuttavia questo ha dato gli stessi risultati. –

+0

Avresti un repository da dove posso testare? Grazie! –

+0

Ho effettuato alcuni test aggiuntivi ma non riesco a riprodurre il problema. Ho definitivamente bisogno di alcune cose (plunkr o github repo) per essere in grado di riprodurre il tuo problema e provare a trovare una soluzione ;-) –

Problemi correlati