Backbone.js视图在创建期间的生命周期

问题描述:

我是backbone.js的新手,对前端工作也有点新意,还没有完全弄清楚生命周期如何工作。Backbone.js视图在创建期间的生命周期

我们有一个Django后端,它为我们提供了html模板,我们基本上只使用它作为框架。所有的逻辑都在Backbone视图中处理。

我现在有的问题是我试图绘制一个图形,但绘图函数没有找到基于id的视图,因为它在渲染函数中不存在,但我没有意识到在稍后的阶段实现这一点。

我试着在Chrome控制台手动创建视图的页面完全加载后,它的工作原理:

var main = new MainView(); 
    main.showChart(); 

的观点:

var ChartView = Backbone.View.extend({ 

    title: 'Chart', 

    initialize: function() { 

    // This assures that this refers to this exact view in each function 
    // (except within asynchronous functions such as jquery each) 
    _.bindAll(this); 

    // Saving parameters given by parent 
    this.index = this.options.index; 

    // Retrieve the template from server 
    var template = _.template(getTemplate('chart.html')); 

    // Compile the template with given parameters 
    var compiledTemplate = template({'title': this.title}); 

    // Set the compiled template to this instance's el-parameter 
    this.$el.append(compiledTemplate); 

    // Rendering the view 
    this.render(); 
}, 

    render: function() { 

    var self = this; 

    // Draw the graph when the page is ready 
    $(function(){ 
     self.drawGraph('chart1', this.line1Data); 
    }); 

    // Render function should always return the instance 
    return this; 
}, 

drawGraph : function(chartId, lineData) { 

    Morris.Line({ 
      element: chartId, 
      data: [ 
      {y: '2012', a: 100}, 
      {y: '2011', a: 75}, 
      {y: '2010', a: 50}, 
      {y: '2009', a: 75}, 
      {y: '2008', a: 50}, 
      {y: '2007', a: 75}, 
      {y: '2006', a: 100} 
      ], 
      xkey: 'y', 
      ykeys: ['a'], 
      labels: ['Series A'] 
    }); 
}, 

});

如果它的创建:

 var chartWidgetView = new WidgetView({'contentView': new ChartView()}); 
    this.initializeWidget(chartWidgetView); 
    this.$el.append(chartWidgetView.el); 

有人能明确对我说:

  1. 如何骨干实际处理视图的创建?什么是不同的阶段?
  2. 我应该如何处理这种情况,例如在我的代码的哪一点将存在HTML模板中的元素,以便我可以调用它的图形函数?
  3. 或者,我的架构是否存在根本上的缺陷?我应该尝试以完全不同的方式做到这一点吗?

FWIW,我认为你是在正确的轨道上。但正如你的问题笔记,你刚刚有一些事情没有秩序。

严格地说,骨干视图没有太多的生命周期。当你实例化一个时,它调用初始化。除此之外,由您来决定视图的生命周期是什么。什么时候它会被渲染。当呈现的el将被附加到DOM,当它将被从DOM中删除时,它将被关闭并销毁。这完全取决于你想如何使用视图。

当然,您还有一些事情要做,并加上让生命周期更易于理解。例如,有几个伟大的框架位于骨干网之上。我建议你看看LayoutManager,Thorax,Chaplin和我自己的制片人作为出发点。

更重要的是,您所描述的插件很可能依赖于插件运行之前DOM中的HTML元素。这是常见的视觉插件,因为他们经常需要捕获位置信息,CSS信息,相关项目的位置等。

有一些非常简单的事情可以做,以促进这些类型的插件,并使这项工作。我已经在这里写了一些,这里:http://lostechies.com/derickbailey/2012/02/20/using-jquery-plugins-and-ui-controls-with-backbone/ - 希望这会帮助你走上正轨。

具体而言,您要查看的是onShow方法的想法。这不是Backbone自己理解的方法。这是一个你必须添加到你的视图和你的应用程序的概念。但好消息是,这很容易。只需将该方法添加到您的视图中,然后在正确的时间调用它:


var AnotherView = Backbone.View.extend({ 
    onShow: function(){ 
    this.$el.layout({ appDefaultStyles: true}); 
    } 
}); 


// instantiate the view 
var view = new AnotherView(); 

// render it 
view.render(); 

// attach it to the DOM 
$("#someDiv").html(view.el); 

// now that it has been attached to the DOM 
// you can call your DOM-dependent plugins 
view.onShow(); 

希望有所帮助。

+0

我能够通过在创建ChartView之后显式调用渲染函数来解决问题,并将其追加到其父项:'chartWidgetView.contentView.render();'。感谢您的优秀见解和链接,我一定会在将来留意这些!我也会重构一下我的代码;) – jesseniem 2012-08-15 12:53:15

只是看着这个我认为问题是模板不是从服务器返回之前,你呈现它,因此它不会出现。您可以使用jQuery的deferred对象解决此问题(请参阅this ref)。尝试在initialize末做这样的事情:

this.deferredTemplate = $el.append(compiledTemplate); 

this.deferredTemplate.done(function() { 
    this.render(); 
}); 

又见德里克贝利的文章deferreds在Backbone.js的:http://lostechies.com/derickbailey/2012/02/09/asynchronously-load-html-templates-for-backbone-views/

+0

我无法解决这个问题。尽管如此,这个优秀的链接+1。 – jesseniem 2012-08-15 12:47:03

要创建的EL但不能将其连接到DOM,和我怀疑图表只搜索要附加到的元素的DOM。您需要在调用drawGraph之前将其附加到DOM。

至于Backbone视图的创建,我认为深入视图的最好方法是简单地阅读带注释的源代码,实际上它并不长。

+0

这是否将它附加到DOM:'this。$ el.append(compiledTemplate);'?或者它只在'this。$ el.append(chartWidgetView.el);'模板实际上成为DOM的一部分吗? – jesseniem 2012-08-15 12:46:14

+0

这两种情况都将模板附加到主干视图的el。如果el在此时连接到DOM,那么模板也是如此。在这种情况下,只有在后一种情况下,el才会连接到DOM。 – tsiki 2012-08-15 13:05:47