Angular 2 - nested component inside an ngFor is copying data to each item in the list

1,124 views
Skip to first unread message

Brian Lee

unread,
Feb 19, 2016, 5:38:30 PM2/19/16
to AngularJS
Goal:  
1) Display a list (data pulled from service)
2) "Load Additional Info" button exists on each item in the list.  Clicking it will load additional data from a server directly

Here is the HTML for <herolist>:
<ul class="heroes">
<li *ngFor="#hero of heroes">
{{hero.ID}}-{{hero.Name}}
<div><a class='link' (click)="GetHero(hero)">Load Additional Hero Info</a></div>
<hero [hero]="selectedHero"></hero>
</li>
</ul>

Here is the HTML for <hero>:
<div *ngIf="hero">
<div>ID:<input [(ngModel)]="hero.ID" type="text" /></div>
<div>Name:<input [(ngModel)]="hero.Name" type="text" /></div>
<div>Power Level:<input [(ngModel)]="hero.PowerLevel" type="text" /></div>
<div><a class='link' (click)="GetHeroDetails()">Load Hero Details</a></div>
<div><herodetails [heroDetails]="heroDetails"></herodetails></div>
</div>

Here is the Hero List Component:
@Component({
    selector: 'herolist',
    providers: [
        HTTP_PROVIDERS,
        HeroService
    ],
    templateUrl: 'views/HeroList.html',
    directives: [HeroComponent],
})
export class HeroListComponent implements OnInit {
    constructor(private _heroService: HeroService) { }

    heroes: Hero[];
    selectedHero: Hero;

    ngOnInit() {
        this.GetAllHeroes();
    }

    GetHero(hero: Hero) {
        this._heroService.getHero(hero.ID)
            .subscribe(res => this.selectedHero = res);
    }

    GetAllHeroes() {
        this._heroService.getAllHeroes()
            .subscribe(res => this.heroes = res);
    }
}


The problem is that when ever I click "Load Additional Hero Info", it loads the data from the server and then sets it for every item in the list, not just the one I want to set.  What am I doing wrong here?  Any help would be appreciated.

Günter Zöchbauer

unread,
Feb 20, 2016, 6:58:36 AM2/20/16
to AngularJS
I guess what you want is

        <div><a class='link' (click)="herodetails.GetHeroDetails()">Load Hero Details</a></div>
<div><herodetails #herodetails [heroDetails]="heroDetails"></herodetails></div>

I added a #herodetails template variable to the <herodetails #herodetails ...> element and use it in (click)="herodetails.GetHeroDetails()" to reference the .GetHeroDetails() in the herodetails component instead of the HeroListComponent (which would be default).

Brian Lee

unread,
Feb 20, 2016, 4:39:23 PM2/20/16
to ang...@googlegroups.com
Thank you. That worked perfectly.

--
You received this message because you are subscribed to a topic in the Google Groups "AngularJS" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/angular/2RdA0JMooEc/unsubscribe.
To unsubscribe from this group and all its topics, send an email to angular+u...@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
Visit this group at https://groups.google.com/group/angular.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages