Marionette ItemView尝试在init中获取之前渲染模板完成

时间:2012-09-12 16:08:28

标签: backbone.js marionette

更新

我为我的项目创建了一个解决方案。我将一个空模板设置为此视图默认模板(实际上包含加载消息和throbber以防任何进一步的延迟)并设置模型更改事件以在准备好时用groupTemplate替换视图$ el html。这在我的开发,测试和生产框中进行了无缝过渡,但是,如果生产在恢复模型数据时变慢,它实际上将显示加载消息。

define([
  'underscore',
  'backbone',
  'marionette',
  'models/group',
  'text!templates/shared/empty.html', // include empty template
  'text!templates/groups/group.html'
], function(_, Backbone, Marionette, groupModel, emptyTemplate, groupTemplate){
  var GroupView = Backbone.Marionette.ItemView.extend({
    initialize: function() {
      var view = this;

      this.model = new groupModel({id:this.options.groupid});

      // listen to the model change and display the real template when fired.
      this.model.on('change', function(){
        view.$el.html(_.template(groupTemplate, view.model.attributes));
      });

      this.model.fetch();
    },
    template: emptyTemplate // display empty template be default
  });
  return GroupView;
});

我有一个使用嵌套列布局的布局(在本例中为三列)。使用相应的视图调用嵌套布局,它需要这些视图并在其自己的区域中显示它们。 (如果有更好的方法,请告诉我。)

我的问题是用于col2的GroupView(嵌套的三列布局)正在使用ItemView并且正在使用没有数据启动的模型。模型使用url而不是集合来检索数据,因此必须使用提取来检索数据。 ItemView正在尝试使用没有数据的模型渲染它的模板,并且无法找到模型字段。给我以下错误。

  

未捕获的ReferenceError:未定义groupname

有没有办法延迟渲染,或者ItemView是否有一个未记录的emptyView,如colletionsView?如果有更好的方法来解决这个问题,请告诉我。

路由器控制器

group: function(groupid) {
  // require and setup our three column layout
  require([
    'views/layouts/three-column', 'views/shared/left-user-menu',
    'views/groups/group', 'views/shared/location'
  ], function(threeColumnLayout, leftView, groupView, locationView) {
  App.wrapper.currentView.main.show(new threeColumnLayout({
    views: {
      col1: new leftView(),
      col2: new groupView({groupid: groupid}),
      col3: new locationView()}
  }));
}

嵌套布局(三栏)

define([
  'underscore',
  'backbone',
  'marionette',
  'text!templates/layouts/three-column.html'
], function(_, Backbone, Marionette, threeColumnTemplate) {
  var Layout = Backbone.Marionette.Layout.extend({
    initialize: function(options) {
      var layout = this;

      this.on('render', function(options){
        layout.col1.show(options.options.views.col1);
        layout.col2.show(options.options.views.col2);
        layout.col3.show(options.options.views.col3);
      });
    },
    tagName: 'div',
    template: threeColumnTemplate,
    regions: {
      col1: '#col1',
      col2: '#col2',
      col3: '#col3'
    }
  });

  return Layout;
});

Group ItemView

define([
  'underscore',
  'backbone',
  'marionette',
  'models/group',
  'text!templates/groups/group.html'
], function(_, Backbone, Marionette, groupModel, groupTemplate){
  var GroupView = Backbone.Marionette.ItemView.extend({
    initialize: function() {
      this.model = new groupModel({id:this.options.groupid});
      this.model.fetch();
    },
    template: groupTemplate
  });
  return GroupView;
});

2 个答案:

答案 0 :(得分:3)

获取并在您知道数据准备就绪后呈现。使用promises可以轻松实现主干提取已经承诺。

initialize: function () {
  var that = this;
  var fetching = this.model.fetch();

  fetching.done(function() { that.render(); });
}

答案 1 :(得分:1)

有类似的问题

Backbone Marionette Displaying before fetch complete

this.model = new groupModel({id:this.options.groupid});

将触发渲染,因为有一个对象被传递。在获取之前 ..

我的正常解决方法是在获取水合物之前为模板需要的任何内容设置一个空白默认值。