7

我是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. Backbone 如何实际处理视图的创建?有哪些不同的阶段?
  2. 我应该如何处理这种情况,例如,html 模板中的元素会在我的代码的哪一点存在,以便我可以为它调用绘图函数?
  3. 还是我的架构存在根本缺陷?我应该尝试以完全不同的方式做到这一点吗?
4

3 回答 3

11

FWIW,我认为你在正确的轨道上。但是正如您的问题所指出的那样,您只是有一些问题。

严格来说,主干视图中并没有太多的生命周期。当您实例化一个时,它会调用初始化。除此之外,由您决定视图的生命周期。什么时候渲染。什么时候渲染的el会被附加到 DOM 上,什么时候会从 DOM 中移除,什么时候会被关闭和销毁。这一切都取决于您希望如何使用视图。

当然,您可以做一些事情并添加一些事情来使这个生命周期更容易理解。例如,有一些很棒的框架位于主干之上。我建议将 LayoutManager、Thorax、Chaplin 和我自己的 Marionette 作为起点。

不过,更重要的是,您所描述的插件很可能依赖于 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();

希望有帮助。

于 2012-08-15T03:57:36.617 回答
1

只是看了一眼,我认为问题在于模板在渲染之前没有从服务器返回,因此它不会出现。您可以使用 jQuery 的deferred对象解决此问题(请参阅此参考资料)。尝试在末尾做类似的事情initialize

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

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

另请参阅 Derick Bailey 关于bone.js 中的延迟的文章:http: //lostechies.com/derickbailey/2012/02/09/asynchronously-load-html-templates-for-backbone-views/

于 2012-08-14T21:11:54.540 回答
1

您正在创建 el 但未将其附加到 DOM,我怀疑图表仅在 DOM 中搜索要附加到的元素。在调用 drawGraph 之前,您需要将其附加到 DOM。

至于 Backbone 视图的创建,我认为获得深入视图的最佳方法是简单地阅读带注释的源代码,实际上并没有那么长。

于 2012-08-14T21:44:21.157 回答