Reputation: 1981
Just went through the Tour of Heroes tutorial app and experienced some interesting behavior within my template. I started the second part of the tutorial with the following code:
class Hero {
id: number;
name: string;
}
@Component({
selector: 'my-app',
template:`
<h1>{{title}}</h1>
<h2>{{hero.name}} details!</h2>
<div><label>id: </label>{{hero.id}}</div>
<div>
<label>name: </label>
<div><input [(ng-model)]="hero.name" placeholder="name"></div>
</div>
`,
directives: [FORM_DIRECTIVES]
})
class AppComponent {
public title = 'Tour of Heroes';
public hero: Hero = {
id: 1,
name: 'Windstorm'
};
}
When instructed to add the array of new heroes (var HEROES: Hero[] = [ /* Hero Data */];
) and the new property to my component, I assumed we were replacing the original hero
property and ended up with this:
class AppComponent {
public title = 'Tour of Heroes';
public heroes = HEROES;
}
Next, the template was modified like so:
<h1>{{title}}</h1>
<ul class="heroes">
<li *ng-for="#hero of heroes">
<span class="badge">{{hero.id}}</span> {{hero.name}}
</li>
</ul>
<h2>{{hero.name}} details!</h2>
<div><label>id: </label>{{hero.id}}</div>
<div>
<label>name: </label>
<div><input [(ng-model)]="hero.name" placeholder="name"></div>
</div>
In the browser, the unordered list then rendered one li
per hero
in the array, but did not print the name
or id
. Crazy. After some tinkering, I realized that if I added the original hero
property back to the AppComponent
class all of the heroes in the array rendered just fine. Also, if I simply removed any template code referencing the hero
property not in the ng-for
loop the list would also render just fine.
Here is what I expected:
In my original version, all of the heroes in the array should be reflected in the unordered list, but then all of the hero values outside of the loop should be undefined or possibly the last item in the list.
When I added back the original hero property, there should be some sort of name collision or some other side effect.
How does this work the way it does?
Edit: Here is the requested plunker: http://plnkr.co/edit/U3bSCaIOOjFdtw9XxvdR?p=preview
Upvotes: 0
Views: 1049
Reputation: 8760
Ok so with your plunker I got a bit more of what you were trying to do and the issues you were having.
My Working plunk with more details is HERE
1. NG-For
When you do a NG-For loop the "#" variable is isolated to be inside the loop only. I renamed it "domhero" so you can see.
You had a few calls to it OUTSIDE of the li object which wouldn't work. I re-wrote it a bit to put all your titles and stuff inside the LI loop.
2. Variables from the object
On the input you were trying to access a variable from inside the ng-for loop which you cant do. Once you close out of a loop you cant access those variables. So I showed where I was binding to, to make it clearer for you.
I think it got confusing when you had so many things named the same thing all over the place (hero, heroes, HEROES, class: hero) if you take a look at the plunker I made I renamed the variables to help mark where they are coming from.
Hope it helps!
p
Upvotes: 1