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 的内容。girl-1 girl-2 继续。

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

这是按预期工作的。

到目前为止的问题是:

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

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

非常感谢

4

1 回答 1

4

所有的编辑视图都出现了,因为所有的 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 );
}

主干事件绑定delegate在视图的el. 因此,如果多个视图共享同一个 DOM 元素el,您将有多个delegates 附加到同一个 DOM 元素,您的事件将是一团内斗。

你的情况有点倒退:模型不拥有视图,视图监视模型和集合并响应它们的事件。您将在文档中看到这一点:

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

[...] 有几个特殊选项,如果通过,将直接附加到视图:model, collection, [...]

通常,您创建一个集合,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.

于 2012-05-19T23:57:10.693 回答