Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在主干子视图中绑定单击事件_Javascript_Events_Backbone.js - Fatal编程技术网

Javascript 如何在主干子视图中绑定单击事件

Javascript 如何在主干子视图中绑定单击事件,javascript,events,backbone.js,Javascript,Events,Backbone.js,我在理解主干子视图中的事件绑定时遇到问题。我的观点定义如下: TenantView = Backbone.View.extend({ events: { "click": "setActive" }, initialize: function() { this.parentEl = this.options.parentEl; return this.render(); }, template: new EJS({ url: '/scripts

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

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);
  }
});
模板只是由一个包含一个
a
li
组成。这样做,我的视图上的点击事件不会被捕获,我的方法
setActive
永远不会被触发

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

正如大家所看到的,当谈到
el
属性的含义时,我完全不知所措

问题是,如何将点击视图绑定到这个视图
setActive
函数

谁能给我点化一下吗

问候
Felix

通过引入您的
parentEl
属性并绕过视图元素的创建,您具有某种禁用的backbones自然行为。您基本上从未将视图的elz属性连接到任何东西

如果我没有弄错代码,
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);
        });
    }
});
首先,你可以阅读和阅读。这里给出了关于
el
的解释

由于
TenantView
具有
parentEl
属性,我假设它是从某个
parent\u视图中呈现的。我会建议一些类似下面的方法,并尝试一下

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;
  }
});

希望能有帮助

旋风,谢谢你的回答。事实上,这几乎就是我正在做的。parentEl属性指向CollectionViews el属性(这是一个ul),因此我可以在ul中呈现我的ChildView。在父集合视图中,我迭代集合模型,并为每个模型创建一个ChildView实例。我觉得,这种方法是完全错误的。嗯,这就是我一直遵循的,对我来说非常有效:)阅读实际上解决了我的问题。见下面我的评论。再次感谢您的意见。托尔斯滕,谢谢您的回复。setElement似乎在渲染期间正确设置了“我的视图”的el属性。不幸的是,这两种方式都无法捕获单击事件。我认为我在CollectionView中呈现ChildView的整个方法是完全错误的。。。主干类希望您在初始化后拥有一个元素,并且仅使用render函数填充该元素。理论上,
setElement
函数应该处理事件。你使用哪个版本的主干网?我使用的是0.9.2。到目前为止,解决这个问题的方法是将ChildView的标记名
设置为'li'。然后从模板中删除li。我将我的ChildView的呈现方法更改为:this.el.innerHTML=this.template.render(this.model),并将我的CollectionView的呈现方法更改为:$(this.el).children('ul').append(viewInstance.render().el),其中viewInstance被迭代。我仍然不确定这种方法是否正确。