2011-10-05 105 views
12

我与Backbone.js的建立一些复杂的视图关系的工作,如果有从做一些看起来像这样的JavaScript性能的角度来看什么问题我想知道:嵌套意见骨干JS

var viewOne = Backbone.View.extend({ 
     tagName : 'li', 
     initialize : function() { 
       this.v2 = new viewTwo({parent:this}); 
     }, 
     clickHideOne : function() { 
       $(this.el).removeClass('selected'); 
     } 
}); 

var viewTwo = Backbone.View.extend({ 
     tagName : 'a', 
     initialize : function() { 
       this.bind('click', this.clickHide, this); 
     }, 
     clickHide(){ 
       $(this.el).removeClass('selected'); 
       this.options.parent.clickHideOne(); 
     } 
}); 

如果是这种两个视图之间的循环引用的一个非常简单的例子中,为了有事件在一个视图中容易向上传播的视图的链,或保持在父视图的对象的任何引用。是否有任何情况下,这会成为一个问题,特别是与IE7 +中DOM元素引用的潜在泄漏相关的问题,还是有其他推荐的用于引用父视图的最佳做法。

而且,据我所知,我可能只是这样做$(this.el).parent( '礼')removeClass( '选择')。鉴于两个,这不是重点......这只是我对循环引用问题的一个非常简单的例子。

回答

15

有负责子视图父视图是不是一个坏主意,是骨干一个相当常见的场景。我在上面的代码中看到的问题是,子视图有其父视图的知识。我建议在viewTwo中使用自定义事件,并让viewOne绑定到这些事件,然后做出相应的响应。

这是通过使用触发器()方法和bind()方法用骨干相当容易。

+0

这听起来像一个很好的方法,我想我也想知道为什么它会特别有害的孩子视图有父视图的知识吗? – tgriesser

+3

因为子对象不负责创建父对象,所以它不应该知道它并且完全独立。你基本上正在创造不必要的依赖。 –

+1

但是,如果父对象存在依赖关系,就不会有意义...就像如果没有父对象的情况下子对象不能存在 - 并且您可以切换哪个对象是视图的“父对象”比必须重新定义绑定和触发 – tgriesser

0

嵌套是保持分层的观点编写维护的代码复杂的用户界面的一个好办法。在这个简单的例子中,几乎没有任何性能问题,但在更复杂的情况下,您需要记住嵌套的深度。 例如,在数千行的网格中使用复杂的单元格渲染器可能会导致应用程序不可用。在这种情况下,通常可以进行聪明的优化,例如。使用渲染器仅用于可见的网格单元格。

2

循环引用是一个坏主意。正如凯尔所说,这也不是一种好的做法,孩子的观点对其父视图有明确的参照。显式引用只能在视图层次结构中向下。也就是说,父视图对所有子视图进行显式引用,并调用子视图的方法与它们进行交互是很好的典型做法。 (请参阅Backbone.Subviews mixin,了解如何创建和管理子视图)。然而,最好的封装实践决定一个视图不应该有明确的引用或直接直接调用其兄弟姐妹或其父母的方法。

为了与兄弟姐妹或父母沟通,你有我所知道的三个选项:

  1. 使用view.trigger()触发的子视图(或兄弟姐妹)的事件,再有父(或兄弟姐妹)使用view.listenTo()收听该事件。这种方法很有效,但是当你想要一个子视图与其祖父通信时,它就开始崩溃了。另外,如果你在同胞中使用这种方法,你会创建不需要的显式依赖项。

  2. 你可以使用Backbone.Courier,它是一个插件,可以很容易地在视图层次结构中冒泡事件。对于同级视图之间的通信,一个兄弟会将一个事件吹到父级,然后父级直接调用另一个兄弟的方法。

  3. 您可以使用event aggregator充当子对象与父对象之间或兄弟对象之间的中间对象。这样,这些视图就可以通过聚合器进行交流,而不会明确地相互引用。但是,这种方法需要全局聚合器对象,并且还允许纵横交错的隐式依赖关系,随着视图数量的增长,这可能变得很难管理。

+0

这3个选项是伟大的处理通信之间的意见..但我只是想知道的情况下,我有一个视图'A'有子视图,其中一个调用模态,当模态结束时触发。该模式打破了层次结构,所以我应该使用Event Aggregator作为我的视图'A'监听它? – mateusmaso