另一个集合视图中的集合视图

Collection view inside another collection view?

本文关键字:集合 视图 另一个      更新时间:2023-12-14

使用backbone.js,我设置了一个appView,它可以很好地渲染内部的两个视图(teamViewplayerView),应用程序视图可以访问两个集合teamsplayers并像这样渲染这两个集合。

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);

这是显而易见的,但结果是这样的。

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

所以你可以看到,当我运行_.each团队时,我将其设置为循环团队视图,然后在它下面设置为循环玩家视图,很明显为什么结果会是这样。

我感到困惑的是,我如何在团队视图中设置球员视图。当然,我已经尝试过在团队视图中循环玩家,但如果不循环团队,我很难运行var teamPlayers = this.players.where({team_id: team.get('id')}) // Organize so that players matches his team id.

在视图中思考它,我可能可以访问this.model.get('id')来代替team.get('id'),并使用它,但每次我提出一个想法时,它都会失败,因为我错过了最微小的细节,我最终会浪费时间。所以我想我可以澄清这一点,得到一些学习,并给出一些观点。

所以最后我想得到这样一个HTML结果。

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

我觉得这是一个很容易的问题,但我通过stackoverflow学到了最好的东西。希望你们知道我在这里的意思,HTML结果解释了一切:)

谢谢!

完整代码:以防万一

/** 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);

您要做的似乎是先添加Team HTML,然后添加Players HTML,再添加Team HTMLPlayers HTML,依此类推。您应该先将Players HTML添加到Team HTML,然后再将Team HTML添加到您的el。试试看这是否有效:

    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);

这只是你正在做的事情,但你应该考虑以更好的方式构建你的观点。