首次单击时将跳过骨干视图中的Jquery事件

时间:2012-02-18 00:29:19

标签: javascript jquery backbone.js

我有一个用于显示和隐藏div的切换事件,它连接在骨干视图中并通过事件委托进行调用。首次单击链接toggle()将被跳过。在第二次和第三次单击切换()按预期调用。

有关如何在首次点击时使用切换事件的任何想法吗?

events:{
    "click a.docSectionHeading" : "Expand" 
  },

  initialize: function(options) {
    _.bindAll(this, "render", **"Expand"**);
    this.model.bind("change", this.render);      
    this.model.fetch();
  },

  render: function() {    
    var $el = $(this.el);
    $el.empty();
    $el.append(this.template.to_html({
      message: this.model.get("message")  
    }));

    return this;
  },

  Expand: function() {

    var tempid = "";
    var id = "";

    // Not called on first click
    $("a.docSectionHeading").toggle(
      function () {

        tempid = $(this).attr("data-id");
        id = tempid.replace(".", "\\.");

         // show -, hide +
        $("img#doc_minus_" + id).removeClass(".noShow");
        $("img#doc_minus_" + id).show();
        $("img#doc_plus_" + id).hide();

        // show clicked section.
        $("#" + id).show();
      },

      function(){
        tempid = $(this).attr("data-id");
        id = tempid.replace(".", "\\.");

         // show -, hide +
        $("img#doc_minus_" + id).addClass(".noShow");
        $("img#doc_minus_" + id).hide();
        $("img#doc_plus_" + id).show();

        // show clicked section.
        $("#" + id).hide();
      }
    )

    return false;
  }

1 个答案:

答案 0 :(得分:2)

jQuery切换绑定点击切换行为,因此当您第一次单击它时,处理切换的事件会被绑定但不会被触发,因为它尚未绑定且没有任何反应,这就是为什么它适用于第二次单击。这里的另一个问题是,现在每次点击你都会反复绑定事件,这将使事件随着时间的推移多次触发,并且它可以产生所有不同类型的难以跟踪的错误+性能将受到影响。

要解决此问题,您需要在渲染模板后生成渲染方法中的toggle事件,或创建辅助方法bindToggle或类似的东西,并在渲染后从渲染方法中调用它模板。

编辑:和一些提示

  • 这是一个广泛接受的标准,我们以小写的形式开始方法的名称,并使用大写的类/构造函数的名称 - 这可能会让其他程序员感到困惑。
  • 你使用empty然后追加 - 它相当于jquery html它将为空,然后追加你的html / DOM节点
  • 如果将事件绑定到元素,则不需要再次查询它,可以使用$(event.target)
  • 从事件对象中获取它
  • 如果您使用的是Backbone 0.9+,则无需使用$(this.el)来获取表示该元素的jquery对象,您可以通过访问this.$el
  • 如果您要查询的元素是当前视图元素的子元素,那么使用主干this.$方法(this.$('a.docSectionHeading'))会更有效,因为它会更有效率,因为它会搜索仅适用于当前元素的子元素。此外,它还允许您查询尚未添加到文档DOM树中的元素。

PS。并希望bindAll中的**"Expand"**只是一个错误?什么是明星?

固定代码:

initialize: function(options) {
  _.bindAll(this, "render");
  this.model.bind("change", this.render);      
  this.model.fetch();
},

render: function() {    
  var $el = $(this.el);
  $el.empty();
  $el.append(this.template.to_html({
    message: this.model.get("message")  
  }));

  this.bindExpand();

  return this;
},

bindExpand: function() {

  var tempid = "",
      id = "";

  this.$("a.docSectionHeading").toggle(
    function () {

      tempid = $(this).attr("data-id");
      id = tempid.replace(".", "\\.");

       // show -, hide +
      $("img#doc_minus_" + id).removeClass(".noShow");
      $("img#doc_minus_" + id).show();
      $("img#doc_plus_" + id).hide();

      // show clicked section.
      $("#" + id).show();
    },

    function(){
      tempid = $(this).attr("data-id");
      id = tempid.replace(".", "\\.");

       // show -, hide +
      $("img#doc_minus_" + id).addClass(".noShow");
      $("img#doc_minus_" + id).hide();
      $("img#doc_plus_" + id).show();

      // show clicked section.
      $("#" + id).hide();
    }
  );
}