2012-05-19 53 views
0

我正在做我的第一个骨干应用程序,并且我尝试附加事件时发生了一件奇怪的事情。对所有视图都支持的骨干视图事件

我得到这个代码至今:

//View for @girl, EDIT action 
GirlEditView = Backbone.View.extend({ 
    initialize: function(el, attr) { 
     this.variables = attr; 
     console.log(attr); 
     this.render(); 
    }, 
    render: function() { 
     var template = _.template($("#girl_edit").html(), this.variables); 
     $(this.el).html(template); 
     $("#edit_girl").modal('show'); 
    } 
}); 

//View for @girl 
GirlView = Backbone.View.extend({ 
    initialize: function(el, attr) { 
     this.variables = attr; 
     this.render(); 
    }, 
    render: function() { 
     var template = _.template($("#girl_template").html(), this.variables); 
     $(this.el).html($(this.el).html() + template); 
    }, 
    events: { 
     "click p.modify": "modify" 
    }, 
    modify: function() { 
     //calls to modify view 
     new GirlEditView({el : $("#edit_girl")}, this.variables); 
    } 
}); 


//One girl from the list 
Girl = Backbone.Model.extend({ 
    initialize: function() { 
     this.view = new GirlView({el : $("#content")}, this.attributes); 
    } 
}); 

//all the girls 
Girls = Backbone.Collection.extend({ 
    model: Girl, 
}); 




//do magic! 
$(document).ready(function() { 

    //Underscore template modification 
    _.templateSettings = { 
     escape : /\{\[([\s\S]+?)\]\}/g, 
     evaluate : /\{\[([\s\S]+?)\]\}/g, 
     interpolate : /\{\{([\s\S]+?)\}\}/g 
    } 

    //get initial data and fill the index 
    var list = []; 
    $.getJSON('girls.json', function(data) { 
     list = []; 
     $.each(data, function(key, val) { 
      list.push(new Girl(val)); 
     }); 

     var myGirls = new Girls(list); 
     console.log(myGirls.models); 
    }); 
}); 

正如你所看到的。

我正在使用一个集合来存储所有的女孩,并且数据来自Ruby中的REST api。

每个女孩创建一个新的模型实例,并在里面附加一个视图实例。

我不知道这是否是一个好的做法,但我想不出一个更好的方法来做到这一点。

每个视图都使用唯一的ID生成内容。女孩1女孩2继续。

现在,该模板有一个编辑按钮。 我最初的想法是攻击onclick事件并触发编辑视图来呈现。

这是按预期工作。

的proble迄今:

当事件触发,所有的集合(女孩)火编辑视图,而不是“拥有”渲染视图之一。

我的问题是我做错了什么?

非常感谢

回答

3

所有编辑观点上来,因为所有的GirlViews都使用相同的el

this.view = new GirlView({el : $("#content")}, this.attributes); 

,然后渲染可以追加更多的HTML:

render: function() { 
    var template = _.template($("#girl_template").html(), this.variables); 
    $(this.el).html($(this.el).html() + template); 
} 

在视图的el上使用delegate绑定主干事件。因此,如果多个视图共享相同的el,那么您将有多个delegate附加到相同的DOM元素,并且您的事件会混乱不清。

你有些事倒退:模特没有自己的观点,观看模特和收藏并回应他们的事件。你会看到这个right in the documentation

构造函数/初始化new View([options])

[...]有迹象表明,如果获得通过,将直接连接到视图几个特殊选项:modelcollection, [...]

一般情况下,您创建一个集合,c,然后交给它该集合创建视图:

var v = new View({ collection: c }) 

,或者你创建一个模型,m,然后围绕该包裹视图模型:

var v = new View({ model: m }) 

然后视图结合于收集或模型事件,以便它可以更新其作为基础数据的变化显示。该视图还充当Backbone中的控制器,并将用户操作转发给模型或集合。

你的初始化应该看起来更像是这样的:

$.getJSON('girls.json', function(data) { 
    $.each(data, function(key, val) { 
     list.push(new Girl(val)); 
    }); 

    var myGirls = new Girls(list); 
    var v  = new GirlsView({ collection: myGirls }); 
}); 

,然后GirlsView将通过收集旋转并为每个模型创建单独GirlView S:

var _this = this; 
this.collection.each(function(girl) { 
    var v = new GirlView({ model: girl }); 
    _this.$el.append(v.render().el); 
}); 

然后,GirlView会使这样的:

// This could go in initialize() if you're not certain that the 
// DOM will be ready when the view is created. 
template: _.template($('#girl_template').html()), 
render: function() { 
    this.$el.html(this.template(this.model.toJSON()); 
    return this; 
} 

结果是,每个每个模型视图将具有其自己的不同el来本地化事件。这也使得添加和删除GirlView非常容易,因为一切都很好地包装在自己的el中。

+0

好吧,我想我得到模型在骨干的观点,我做了改变,但现在什么都没有显示在页面http://pastebin.com/96vhsDPu – nax

+0

@nax:你没有呈现你的'GirlsView “任何地方; 'this.collection.each'循环可能在'render'而不是'initialize'中更好:http://jsfiddle.net/ambiguous/3fHkh/ –