木偶复合视图。表中每个单元格的视图

时间:2013-11-19 10:18:14

标签: javascript backbone.js marionette

我想用木偶来渲染一张桌子来制作生命游戏。我发现的所有例子都是一个 CompositeView并有一个表示行的itemView。这不是那么好,因为如果任何单元格改变,那么整个行将再次渲染。

如果你能得到这样的话会很棒:

CompositeView (for the table and table body)
    has a collection of row collections
    has a CollectionView (that represents a row)
        has a collection of Cells that are rendered by a ItemView

更新 代码当前打印出您期望的网格广告,但由于Game.RowView在初始化程序中分配集合,因此当集合中的模型发生更改时,它似乎不会监听事件,因此模型视图不是被重新渲染。

要查看代码视图,此jsfiddle封装了问题http://jsfiddle.net/LPg2x/12/ 已更新

更新

<div id="gameRegion"></div>
<script id="gridTemplate" type="template-x-handlebars">
    <tbody></tbody>
</script>

更新

    var GameOfLife = new Backbone.Marionette.Application();
GameOfLife.addRegions({
    gameRegion: "#gameRegion"
});

// Create a var for the module where everything lives
var Game = GameOfLife.module("Game");

// The controller that will create all of the cells and the GridView. Showing it in the gameRegion
Game.Controller = Backbone.Marionette.Controller.extend({
    initialize: function (options) {
        var rowArray = [];
        for (var rowCounter = 0; rowCounter < options.rows; rowCounter++) {
            var cellArray = [];
            for (var columnCounter = 0; columnCounter < options.columns; columnCounter++) {
                cellArray.push(new Game.Cell());
            }
            rowArray.push(new Game.Row({
                cellCollection: new Game.CellCollection(cellArray)
            }));
        }
        var gridView = new Game.GridView({
            collection: new Game.RowCollection(rowArray)
        });
        GameOfLife.gameRegion.show(gridView);
    }
});

// Model for a cell that starts off being alive
Game.Cell = Backbone.Model.extend({
    defaults: {
        state: "ALIVE"
    },
    toggleState: function(){
        if(this.get("state") === "ALIVE"){
            this.set("state", "DEAD");
        }
        else{
            this.set("state", "ALIVE");
        }
        console.log("Toggle state on model " + this.cid);
    }
});

Game.CellCollection = Backbone.Collection.extend({
    model: Game.Cell
});

Game.Row = Backbone.Model.extend();

Game.RowCollection = Backbone.Collection.extend({
    model: Game.Row
});

// View for a cell. Its just a td and the template will render the models state
Game.CellView = Backbone.Marionette.ItemView.extend({
    template: function(){
        return "";
    },
    className: function(){
        return this.model.get("state") === "ALIVE" ? "alive" : "dead";
    },
    tagName: "td",
    events: {
        "click" : "toggleState"
    },
    toggleState: function(){
        this.model.toggleState();
    }
});

// CollectionView for a row. Its just a tr, which will have all its cells/tds rendered into it
Game.RowView = Backbone.Marionette.CollectionView.extend({
    tagName: "tr",
    itemView: Game.CellView,
    initialize: function(){
        this.collection = this.model.get("cellCollection");
    }
});

// CompositeView for the table. The template create the structure and we render the rows into the tbody
Game.GridView = Backbone.Marionette.CompositeView.extend({
    template: Handlebars.compile($("#gridTemplate").html()),
    tagName: "table",
    itemView: Game.RowView,
    itemViewContainer: "tbody"
});

// Create a new controller instance when the game module is loaded with the application
Game.addInitializer(function (options) {
    var controller = new Game.Controller(options);
});

// Start the game with a 10x10 grid
GameOfLife.start({
    rows: 10,
    columns: 10
});

0 个答案:

没有答案