2013-02-06 46 views
2

我试图想出一个办法让我的私人活动和辅助方法,真正私有的。每个对象只应公开允许被称为外部的东西(激进的,我知道!)。我有一个很难的方式,这样做与骨干网访问量:私人事件处理视图

  1. 不牺牲可读性
  2. 不涉及到很多的样板
  3. 的没有任何意想不到的后果

这里是我的普通视图结构:

(function(){ 
    //Private function no other view needs to care about 
    var addStuffToMyDom = function(model){ 
     var newView = new Subview({model: model}); 

     //Problem: this doesn't refer to the 'view' here 
     this.$el.append(newView.render().$el); 
    } 

    //Another trivial function which should really be private 
    var doSomeThingTrivial = function(){ 
     this.$el.addClass("meh"); 
    } 

    return BaseView.extend({ 
     events: { 
      "click": doSomeThingTrivial 
     }, 

     render: function(){ 
      var me = this; 
      this.collection.each(addStuffToMyDom); 
      return this; 
     } 
    }); 
}()); 

正如你所看到的私有函数不能参照的文ce'this'来追求自己。

解决方案1:

(function(){ 
    var me; 

    ... 

    return BaseView.extend({ 
     initialize: function(){ 
      me = this; 
     } 
    }); 
}()); 

这有很多微妙的副作用+将是恼人的有这都必须这样做。

解决方案2:

(function(){ 
    var me; 

    ... 

    return BaseView.extend({ 
     events{ 
      "click" : function(){ 
       doSomeThingTrivial.call(this); 
      } 
     } 
    }); 
}()); 

这工作,但它是乱码了很多的样板。

解决方案3:

(function(){ 
    return BaseView.extend({ 
      events: {..} 
     initialize: function(){ 
      _.bindAll(this, this.events); 
     } 
    }); 
}()); 

我喜欢这个最好的;这是有效的,它具有相当的可读性并且可以像广告一样工作,但是,对于每个视图而言,这又是一个额外的步骤。我失踪的任何其他解决方案?

+0

为什么不doSomethingTrivial'的'函数体只是直接传递到事件?这样它就只存在于匿名事件处理程序中,而不是作为你的类/视图/任何对象的方法。 – Mathletics

+0

@Mathletics可能的,但如果它在未来它会留下一个巨大的事件哈希增长“不是那么微不足道”。 – Naren

+0

我没有看到一个真实的用例,在这个用例中你想要强制当前JavaScript实现中不支持事件的东西。根据我在小型和大型项目上的经验,最好保持团队成员之间的良好沟通,并记录哪些方法适用于所有人,哪些方法不适用于哪些方法。另外,如果您打算重用您的“课程”,通过将代码安排在关闭中将会使您的生活更加艰难。我真的推荐你尝试这个组合:RequireJS + Backbone + Backbone-Super。 –

回答

1

才发现_.bindAll(本)在私有函数初始化修复范围的问题。我已经长大不太相信这种设计模式,因为我问过这个问题,但它确实解决了吧:)

(function(){ 
    //Private function no other view needs to care about 
    var addStuffToMyDom = function(model){ 
     var newView = new Subview({model: model}); 

     //Problem: this doesn't refer to the 'view' here 
     this.$el.append(newView.render().$el); 
    } 

    //Another trivial function which should really be private 
    var doSomeThingTrivial = function(){ 
     this.$el.addClass("meh"); 
    } 

    return BaseView.extend({ 
     events: { 
      "click": doSomeThingTrivial 
     }, 

     initialize: function(){ 
      _.bindAll(this); 

     } 
    }); 
}()); 
1

你可以通过你想要使用的each方法的上下文:

this.collection.each(addStuffToMyDom, this);

现在this将里面addStuffToMyDom你的看法。

我想,当你使用骨干事件哈希挂钩的事件,它没有类似的东西。你确定this不是doSomeThingTrivial里面的视图吗?

如果你看一下骨干delegateEvents,它这样做:

method = _.bind(method, this);

哪里this您的看法。