在动态呈现视图后将事件绑定到视图的el

时间:2013-09-03 02:51:52

标签: javascript backbone.js

<div class="container"> // this is the parent div template (already existing in the DOM prior to instantiating the View

HTML模板:

  <div id="measure-cid1"> // the number is dynamic
    <div class="row-fluid">
      <div class="remove-measure-rep"><i class="icon-minus"</i></div>
    </div>
    …other stuff…
  </div>
  <div id="measure-cid2">
    <div class="row-fluid">
      <div class="remove-measure-rep"><i class="icon-minus"</i></div>
    </div>
    …other stuff…
  </div>
  … multiple other 'measure-cid*'s
// remaining portion from the parent div template
</div>

BB JS查看:

define([…], …){ //using require
  return Backbone.View.extend({
    // I can not define the el here, as it is dynamic, so I have to set it in the init
    events : {
      'click .remove-measure-rep' : 'removeRepresentation',
      'click' : 'removeRepresentation'
    },
    initialize: function(options){
      if (options) {
        //passing options.* to this view as this.*
        for (var key in options) {
          this[key] = options[key];
        }
        console.log(this.el); // I get `<div></div>`
        this.el = '#measure-rep-'+this.measureRepModel.cid;
        console.log(this.el); // This returns `#measure-rep-c28`
        this._ensureElement();
        console.log(this.el); //This returns `undefined`
        this._ensureElement($('#measure-rep-'+this.measureRepModel.cid));
        console.log(this.el); //this returns `<div></div>`
        this.setElement($('#measure-rep-'+this.measureRepModel.cid));
        console.log(this.el); // this returns `undefined`
      }

      //Dispatch listeners
      …  
      //Binding  
      this.model.bind('change', _.bind(this.render, this));

      this.render();
    },
    render: function(){
      // I attach the template to its parent div 
      var compiledTemplate = _.template( MeasureRepTemplate, measureRepTemplateParamaters );
      // put in the rendered template in the measure-rep-container of the measure
      $(this.repContainerEl).append( compiledTemplate );

    },
    removeRepresentation: function(ev){
      console.log('getting here');
    }
  })
};

在读取el之后,即使作为临时持有者在init之前创建,我也无法弄清楚如何捕获类'.remove-measure-rep'的点击。我还在模板上验证了类remove-measure-rep在模板中,而不是在其他地方,因为看起来其他SO问题没有得到事件捕获处理View只在他们自己的模板中查找类或ID。 View应该创建HTML,并将其添加到DOM。

如何让View访问click事件?,因为当我将el设置为init中的不同值时,它没有注册。我单独尝试了每一个,它仍然无法正常工作。是否与在div中设置模板然后尝试将模板中的元素绑定到VIew有关?

1 个答案:

答案 0 :(得分:1)

  1. 不要混淆this.el。让骨干为您定义视图的元素
  2. 在您的模板中,省略最外面的<div>标记,因为它将是主干
  3. render内,只需设置您想要的ID
  4. 即可
    Backbone.View.extend({
        events : {
          'click .remove-measure-rep' : 'removeRepresentation',
          'click' : 'removeRepresentation'
        },
        initialize: function(options){
          if (options) {
            //passing options.* to this view as this.*
            for (var key in options) {
              this[key] = options[key];
            }
            //don't mess with this.el at all
          }
    
          //Dispatch listeners
          …  
          //Binding
          //better to use listenTo here
          this.listenTo(this.model, 'change', _.bind(this.render, this));  
          //I think initialize calling render is an antipattern. Discouraged.
          this.render();
        },
        render: function(){
          //Here you can set your dynamic ID
          this.$el.attr('id', 'measure-cid' + this.model.id);
          // I attach the template to its parent div 
          var compiledTemplate = _.template( MeasureRepTemplate, measureRepTemplateParamaters );
          // put in the rendered template in the measure-rep-container of the measure
          //view's appending themselves to the DOM is also an antipattern in my book, but anyway..
          $(this.repContainerEl).append( compiledTemplate );
    
        },
        removeRepresentation: function(ev){
          console.log('getting here');
        }
      })
    };