InnerView 不响应其模板中的 DOM 事件

InnerView not responding to DOM events in its template

本文关键字:DOM 事件 不响应 InnerView      更新时间:2023-09-26

问题:当我在另一个视图的范围内创建主干视图时,内部视图没有响应源自其模板内部的 DOM 事件,但是,外部视图正在响应这些事件。在下面的示例中,内部视图有一个提交按钮,但只有外部视图会响应提交按钮的单击

我正在制作一个 Backbone 项目,该项目为路由器中的每个路由创建一个新的主视图,并且该主视图可能具有其页面不同部分的子视图。例如,有一个创建订单视图页面的order路由

routes: {
            'order': 'orderProduct'
        },
orderProduct: function(){
            this.loadView(new OrderView()); 
        },
在 OrderView

的初始化函数中,我为 OrderView 创建子视图,例如 formView。

 var OrderView = Backbone.View.extend({

        initialize: function(){
            $("body").html(this.el);
            this.template = _.template($('#order-template').html()),
            this.subViews = [];
            var formView = new FormView();
            this.subViews.push(formView);
            this.render();
        }, 

然后在 FormView 中,我创建显而易见的,例如提交按钮

 var FormView = Backbone.View.extend({
        el: '#forForm',
        initialize: function(){
            this.template = _.template($('#form-template').html());
        },
        events: {
            'click #submitButton' : 'submitForm',
            },
        submitForm: function(){
            ...
        },
        render: function(){
            $('#forForm').append(this.template());
            return this;
        } 
     });

表单呈现到页面,但是当我单击提交时没有任何反应。然后,我将事件处理程序和相应的函数'click #submitButton' : 'submitForm',添加到 OrderView,它响应了提交事件。所以我的问题是,当我在 OrderView 范围内创建 FormView 时,为什么 FormView 无法响应其模板范围内的事件?

表单模板

   <script type="text/template" id="form-template">
    <button id="submitButton">submit</button>
   </script>

更新:

我应该注意,附加表单模板(由内部视图呈现)的 dom 元素包含在订单模板(外部视图)中。即使如此,由于 FormView 响应的事件源自表单模板内的单击(即单击提交按钮时),我认为 FormView 能够响应这些事件。

<script type="text/template" id="order-template">
  <div class="container">
    <div class='row'>
      <div class="col-md-6">

     <div id="forForm">
     </div>

      </div> 
      <div class="col-md-6">
     ...ommitted...
      </div> 
  </div>
  </div>
</script>

我不确定我是否完全理解这个问题,但我会尝试通过解释一些逻辑来回答这个问题。

主干依赖于 jquery on来注册由 DOM 触发的事件。
这意味着,当您实例化 Backbone 视图并定义其events: {}对象时,您的视图将能够侦听这些事件,并将视图的el作为父元素,来自所有子元素的事件将冒泡到其中。

如果父视图定义了包装子视图上定义的el'sel,则从逻辑上讲,这些事件将冒泡到最高的父视图。
如果父视图还决定监视与内部视图相同的子元素上的单击事件,则此事件将冒泡到最高的父元素,除非您决定从子视图结束传播,这可以通过从处理子视图中事件的方法调用$(event.currentTarget).stopPropagation()来实现。

我希望这是有道理的,并帮助您解决问题。

出于某种原因,在从 OrderView 的呈现函数呈现 FormView 时,我不得不使用 setElement,将 OrderView 容器设置为 FormView 的元素。我不知道为什么这是必要的。我见过许多在另一个视图中呈现一个视图的 Backbone 应用程序(例如,对ul和列表中的每个li使用单独视图的应用程序),这似乎从来都没有必要

这是来自订单视图的呈现函数的相关代码

        _.each(this.subViews, function(view) {          
            view.setElement( this.$el.find('.orderview-container') ).render().el;           
        }, this);