0

我在理解 Backbone 子视图中的事件绑定时遇到问题。我的观点定义如下:

TenantView = Backbone.View.extend({
  events: {
    "click": "setActive"
  },
  initialize: function() {
    this.parentEl = this.options.parentEl;
    return this.render();
  },
  template: new EJS({
    url: '/scripts/templates/tenant.ejs'
  }),
  render: function() {
    $(this.parentEl).children('ul').append(this.template.render(this.model));
    return this;
  },
  setActive: function(event) {
    return this.model.set('active', true);
  }
});

模板只包含一个li包含一个a. 这样做,我的视图上的点击事件不会被捕获,我的方法setActive永远不会被触发。

el当我通过像我的 (2) 视图之一这样的属性扩展我的视图时,el: 'li'它会正常运行并触发该setActive功能。第二种观点根本没有反应。如果我el在视图初始化期间检查该属性,则工作视图的el属性指向右侧li,失败的视图el指向li可以在页面中找到的第一个。

可以看出,当谈到属性的含义时,我完全迷失了el

问题是,我怎样才能将点击视图绑定到这个视图setActive功能?

任何人都可以启发我吗?

问候菲利克斯

4

2 回答 2

2

首先,您可以阅读文档thisel那里给出了解释。

与财产一样,我假设它是从TenantView一些. 我会建议一些类似下面的方法并试一试。parentElparent_view

var ChildView = Backbone.View.extend({
  tagName : "li", // change it according to your needs

  events : {
    "click": "setActive"
  },

  initialize : function() {
    _.bindAll(this, "setActive");
    // code to initialize child_view
  },

  render : function() {
    // as I'm not familiar with the way you are using template, 
    // I've put simple call to render template, but it should render the
    // content to be kept inside "li" tag
    this.$el.html(this.template()); 

    return this;
  },

  setActive : function(event) {
    // code to be executed in event callback
  }
});


var ParentView = Backbone.View.extend({
  el : "#parent_view_el",

  initialize : function() {
    // parent view initialization code
  },

  render : function() {
    // a place from where ChildView is initialized
    // might be a loop through collection to initialize more than one child views
    // passing individual model to the view

    var child_view = new ChildView();

    this.$("ul").append(child_view.render().$el); // equivalent to this.$el.find("ul")

    return this;
  }
});

希望能帮助到你 !!

于 2012-11-07T12:18:22.933 回答
0

通过引入您的parentEl属性并规避视图元素的创建,您有一种禁用的骨干自然行为。您基本上永远不会将视图 `elz 属性连接到任何东西。

如果我的代码正确,则TenantView它是租户列表中的单个列表项。

在您的TenantView项目中,您可以这样做以利用内置事件的主干:

render: function() {
    this.setElement(this.template.render(this.model));
    $(this.parentEl).children('ul').append(this.$el);
    return this;
}

setElement函数将使用您的template函数的返回值来连接视图元素并为您设置事件。在文档中,建议使用setElement以支持仅将某些内容分配给el属性。还有一个漂亮的$el属性,它将包含视图元素的缓存 jQuery(或 Zepto)对象。

为了个人更多地以骨干方式进行,我会考虑这样的事情:

var TenantView = Backbone.View.extend({
    // =========
    // = Setup =
    // =========

    events: {
        "click": "setActive"
    },

    template: new EJS({
        url: '/scripts/templates/tenant.ejs'
    }),

    // =============
    // = Lifecycle =
    // =============

    initialize: function(model, options) {
        this.render();
    },

    render: function() {
        var content = this.template.render(this.model);
        this.$el.html(content);
        return this;
    },

    // ==========
    // = Events =
    // ==========

    setActive: function(event) {
        return this.model.set('active', true);
    }

});


var TenantList = Backbone.View.extend({

    // =========
    // = Setup =
    // =========

    id: "tenantList",
    tagName: "ul",

    // =============
    // = Lifecycle =
    // =============

    initialize: function() {
        this.render();
    },

    render: function() {
        if (this.collection.length > 0) {
            this.renderChildren();
        }
    },

    renderChildren: function() {
        var that = this;

        this.collection.each(function(tenant) {
            that.$el.append(new TenantView(tenant).$el);
        });
    }
});
于 2012-11-07T11:56:38.280 回答