在主干js中的视图中嵌套视图

时间:2011-10-05 23:04:21

标签: javascript jquery dom backbone.js circular-reference

我正在使用backbone.js构建一些复杂的视图关系,我想知道从javascript性能角度来看是否存在任何问题,看起来像这样:

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('li')。removeClass('selected');在视图中,这不是重点......这只是我对循环引用的一个非常简单的例子。

3 个答案:

答案 0 :(得分:15)

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

通过使用trigger()方法和bind()方法,使用骨干很容易。

答案 1 :(得分:2)

循环引用是一个坏主意。正如Kyle所说,儿童观点明确提及其父观点也是不好的做法。显式引用应仅在视图层次结构中向下。也就是说,父视图具有对其所有子视图的显式引用以及调用子视图的方法以与它们交互是很好的,也是典型的。 (有关创建和管理子视图的每种方式,请参阅Backbone.Subviews mixin)。但是,最好的封装实践要求视图不应该有明确的引用或直接直接调用其兄弟姐妹或其父母的方法。

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

  1. 使用view.trigger()触发子视图(或兄弟)上的事件,然后让父(或兄弟)使用view.listenTo()监听该事件。当您希望子视图与其祖父等进行通信时,此方法可以工作但会开始崩溃。此外,如果您将此方法与兄弟姐妹一起使用,则会创建不需要的显式依赖项。

  2. 您可以使用Backbone.Courier,这是一个插件,可以轻松地在视图层次结构中冒泡事件。对于兄弟视图之间的通信,一个兄弟会将事件冒泡到父母,然后父母直接调用另一个兄弟的方法。

  3. 您可以使用event aggregator充当孩子和父母之间或兄弟姐妹之间的中间对象。这样,这些视图可以通过聚合器进行通信,而无需相互明确引用。但是,这种方法需要全局聚合器对象,并且还允许隐含依赖关系的交叉,随着视图数量的增加,这些依赖关系变得难以管理。

答案 2 :(得分:0)

嵌套是维护分层视图以便为复杂用户界面编写可维护代码的好方法。在简单的示例中几乎没有任何性能问题,但在更复杂的情况下,您需要记住嵌套的深度。 例如,在数千行的网格中不正确地使用复杂的单元格渲染器可能会使您的应用程序无法使用。在这种情况下,通常可以进行巧妙的优化,例如。仅对可见网格单元使用渲染器。