2015-10-01 13 views
6

Używam angular2 alfa 37.elementy Generowanie dziecko w angular2 z NgFor nie działa

ja zdefiniował <map> składnik i <marker> komponent (Child of <map>). Komponent ma element danych tablicy, który zawiera listę współrzędnych znacznika. Widok <map> powinien wyświetlić wszystkie znaczniki w tablicy

Podczas definiowania widoku <map> następująco (jawnie sprzedaż komponentów do wszystkich członków tablicy):

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

W <marker> komponenty są aktualizowane w miarę odpowiednie zmiany członków tablicą. To pożądane zachowanie.

Definiując widok <map> w następujący sposób (przy użyciu NgFor)

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

nowy marker powstaje, gdy zmienia elementy macierzy, co nie jest pożądane.

Igły do ​​powiedzenia Chciałbym użyć metody NgFor.

Nie mam pojęcia, co się dzieje. Jak mogę używać NgFor, ale unikaj tworzenia nowych instancji <marker>, gdy aktualizowane są poszczególne znaczniki?

+0

trochę więcej informacji: kiedy '' komponent jest tworzony, to faktycznie tworzy znacznik na mapie ulotki. Kiedy komponent jest aktualizowany, znacznik na mapie powinien zostać zaktualizowany –

Odpowiedz

0

spróbować tej

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

Dziękuję za twój wkład, ale to daje takie same wyniki. Przy każdej zmianie '# m' tworzony jest nowy znacznik, zamiast aktualizowany. –

3

podzielić listę ngFor iteracje na podstawie danych modelowych.

Jest to kod Dart ale nie powinno być trudne do przetłumaczenia na 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

Działa to zgodnie z oczekiwaniami. Szkoda, że ​​to jawne użycie indeksów jest wymagane w tym przypadku użycia. Sprawdzę też inną odpowiedź przed przyznaniem ostatecznej nagrody –

+1

Ponadto, spodziewam się, że poniższe również będą działać, ale tak nie jest: ' ' –

+1

A jak to się dzieje, gdy tablica' markerów' dynamicznie zmienia długość? Odpowiednie "markeryIndeksy" będą musiały być ponownie obliczone przez cały czas? –

0

Widziałem, że używasz wersji alpha37 który pozostaje wersja alfa i możesz mieć jakieś błędy ... Zrobiłem kilka testów używając wersji beta0 i wydaje się działać zgodnie z oczekiwaniami. Więc polecam uaktualnienie do tej wersji ...Oczekujemy, że wersje beta są bardziej stabilne ;-)

Oto kod Kiedyś wykonane mojego testu:

  • główny składnik

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

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

    @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 komponent

    @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'; 
        } 
    } 
    

Kiedy klikam na obu przycisków aktualizacji, nazwę drugiego markera jest aktualizowana w widoku i nie pojawia się żaden dodatkowy <marker> elementem.

Edit

To może być sposób zaktualizować element na liście. Czy przesłonisz go nową instancją lub zaktualizujesz wartość atrybutu istniejącej instancji na liście? W pierwszym przypadku myślę, że możesz dodać nowy element do listy.

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

Po wykonaniu niektórych testów to podejście działa również. Żaden element nie został dodany na liście.

Nadzieję, że to pomaga, Thierry

+0

Dzięki za twój wkład. Przed rozpoczęciem bounty zaktualizowałem ją do najnowszej wersji beta. Jednak dało to takie same wyniki. –

+0

Czy masz repozytorium, z którego mogę przetestować? Dzięki! –

+0

Zrobiłem kilka dodatkowych testów, ale nie mogę odtworzyć twojego problemu. Zdecydowanie potrzebuję kilku rzeczy (plunkr lub github repo), aby móc odtworzyć twój problem i spróbować ustalić poprawkę ;-) –

Powiązane problemy