Reputation: 13492
Using backbone.js I have setup an appView
that nicely renders two views inside (teamView
and playerView
), the app view has access to both collections teams
and players
and renders both collections like this.
this.teams.each(function(team) {
var teamView = new TeamView({ model: team }); // New instance of the team view
var teamHtml = teamView.render().el; //So I set the html as a list of teams
this.$el.append(teamHtml); // Append it
var teamPlayers = this.players.where({team_id: team.get('id')}) // Organize so that players matches his team id.
console.log(teamPlayers)
_.each(teamPlayers, function(player) { // Run a list of the associated players to team
var playerView = new PlayerView({ model: player }); // New instance of the player view
var playerHtml = playerView.render().el; //set the html as a list of players
this.$el.append(playerHtml); //append it
console.log(player.toJSON());
}, this);
}, this);
Now this is obvious but the result is like this.
<ul>// The root of the app view
<div>// The root of the team view
<strong>Lakers</strong>
</div>
<li>Kobe Bryant</li>// The root of the player view
<li>Pau Gasol</li>// The root of the player view
<div>// The root of the team view
<strong>Heat</strong>
</div>
<li>LeBron James</li>// The root of the player view
<li>Dwayne Wade</li>// The root of the player view
</ul>
So you can see, that when I run _.each
team I set it to loop the team view, then under it I set it to loop the players view, it's obvious why that result looks like that.
Where I am confused is how do I set the players view inside the team view. Of course I have tried looping the players inside the team view itself, but without looping teams I have a hard time running var teamPlayers = this.players.where({team_id: team.get('id')}) // Organize so that players matches his team id.
Thinking about it inside the view I could possibly have access to this.model.get('id')
in replace of team.get('id')
and use that instead, but every time I come up with an idea it fails because I am missing the smallest of details, and I end up wasting time. So I figure I can clarify this, get some learning and give out some points.
So finally I want to get an HTML result like this.
<ul>// The root of the app view
<div>// The root of the team view
<strong>Lakers</strong>// This isn't important just need it inside the view
<li>Kobe Bryant</li>// The root of the player view
<li>Pau Gasol</li>// The root of the player view
</div>
// You see the difference, the player view is now inside the team view and both are inside the app view.
<div>// The root of the team view
<strong>Heat</strong>// Again this isn't important just need it inside the view
<li>LeBron James</li>// The root of the player view
<li>Dwayne Wade</li>// The root of the player view
</div>
</ul>
I feel like this is quite an easy question, but I learn best through stackoverflow. Hope you guys know what I mean here, the HTML result explains it all :)
Thanks!
FULL CODE: Just in case
/** PLAYER MODEL **/
var Player = Backbone.Model.extend({
defaults: {
name: "Kobe Bryant",
team: "Los Angeles Lakers",
number: 24,
position: 'guard',
hair: true
}
});
/** TEAM MODEL **/
var Team = Backbone.Model.extend({
defaults: {
id: 1,
name: 'SomeTeam'
}
});
/** PLAYER COLLECTION **/
var PlayersCollection = Backbone.Collection.extend({
model: Player,
});
/** TEAM COLLECTION **/
var TeamsCollection = Backbone.Collection.extend({
model: Team,
});
/** APP COLLECTION VIEW **/
var AppView = Backbone.View.extend({
tagName: 'ul',
template: _.template( $('#allTemplate').html() ),
initialize: function(options) {
this.teams = options.teams || new Teams([]);
this.players = options.players || new Players([]);
},
render: function() {
var self = this;
this.teams.each(function(team) {
var teamView = new TeamView({ model: team });
var teamHtml = teamView.render().el;
this.$el.append(teamHtml);
var teamPlayers = this.players.where({team_id: team.get('id')})
console.log(teamPlayers)
_.each(teamPlayers, function(player) {
var playerView = new PlayerView({ model: player });
var playerHtml = playerView.render().el;
this.$el.append(playerHtml);
console.log(player.toJSON());
}, this);
}, this);
return this;
}
});
/** <li> Player View </li> **/
var PlayerView = Backbone.View.extend({
tagName: 'li',
template: _.template( $('#playerTemplate').html() ),
events: {
'click button':'alert'
},
initialize: function() {
//console.log(this.model.set('name', 'Lance'));
},
render: function () {
this.$el.html( this.template( this.model.toJSON() ) );
return this;
},
alert: function() {
alert('DONE! ' + this.model.get('name') )
}
});
/** <div> Team View </div> **/
var TeamView = Backbone.View.extend({
tagName: 'div',
template: _.template( $('#teamTemplate').html() ),
render: function () {
this.$el.html( this.template( this.model.toJSON() ) );
return this;
}
});
var playersCollection = new PlayersCollection([
{
name: 'Kobe Bryant',
team: 'Los Angeles Lakers',
team_id: 1,
number: 24
},
{
name: 'Lebron James',
team: 'Miami Heat',
team_id: 2,
number: 6
},
{
name: 'Dwayne Wade',
team: 'Miami Heat',
team_id: 2,
number: 3
},
{
name: 'Michael Beasley',
team: 'Miami Heat',
team_id: 2,
number: 3
},
{
name: 'Ron Artest',
team: 'New York Knicks',
team_id: 3,
number: 15
},
{
name: 'Karl Malone',
team: 'Los Angeles Lakers',
team_id: 1,
number: 33
},
{
name: 'Damion Lillard',
team: 'Portland Trailblazers',
team_id: 4,
number: 3
},
{
name: 'Westly Matthews',
team: 'Portland Trailblazers',
team_id: 4,
number: 55
},
{
name: 'Wilt Chamberlin',
team: 'Los Angeles Lakers',
team_id: 1,
number: 17
}
]);
var teamsCollection = new TeamsCollection([
{
id: 1,
name: 'Lakers'
},
{
id: 2,
name: 'Heat'
},
{
id: 3,
name: 'Knicks'
},
{
id: 4,
name: 'Trailblazers'
}
]);
// RUN!!
var appView = new AppView({ players: playersCollection, teams: teamsCollection });
$(document.body).append(appView.render().el);
Upvotes: 0
Views: 58
Reputation: 1638
What you seem to be doing is appending Team HTML
then Players HTML
then again Team HTML
and Players HTML
and so on. You should rather add Players HTML
to Team HTML
and then add Team HTML
to your el
. Try if this works :
this.teams.each(function(team) {
var teamView = new TeamView({ model: team });
var teamHtml = teamView.render().el;
var teamPlayers = this.players.where({team_id: team.get('id')})
console.log(teamPlayers)
_.each(teamPlayers, function(player) {
var playerView = new PlayerView({ model: player });
var playerHtml = playerView.render().el;
// Add player HTML to Team HTML
$(teamHtml).find('div').append(playerHtml);
console.log(player.toJSON());
}, this);
// Add Team HTML to el
this.$el.append(teamHtml);
}, this);
This is just w.r.t to what you are doing but you should think of structuring your views in a better way.
Upvotes: 1