我想用木偶来渲染一张桌子来制作生命游戏。我发现的所有例子都是一个 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
});