Backbone.js Backbone.marionnette-重新绑定事件与创建新视图

Backbone.js Backbone.marionnette-重新绑定事件与创建新视图,backbone.js,marionette,backbone-events,Backbone.js,Marionette,Backbone Events,我有一个布局,它有几个选项卡。单击其中一个选项卡将在页面的内容区域中显示相应的复合视图。在不同选项卡之间来回导航后,我注意到复合视图已经失去了在集合重置和模型更改时要呈现的本机绑定 在第二次显示视图时,我是否应该重新绑定复合视图的\u initialEvents中使用的事件,或者应该在每次显示选项卡时创建一个新的复合视图 当前,我正在我的布局的初始化中创建所有视图,然后在单击选项卡时对视图使用show initialize: function(){ _.bindAll(this);

我有一个
布局
,它有几个选项卡。单击其中一个选项卡将
在页面的内容
区域中显示相应的复合视图。在不同选项卡之间来回导航后,我注意到复合视图已经失去了在集合重置和模型更改时要呈现的本机绑定

在第二次显示视图时,我是否应该重新绑定复合视图的
\u initialEvents
中使用的事件,或者应该在每次显示选项卡时创建一个新的复合视图

当前,我正在我的
布局的
初始化
中创建所有视图,然后在单击选项卡时对视图使用
show

initialize: function(){
    _.bindAll(this);

    //     Tabs
    this.places_page   = new Places_Layout();
},

show_places_page: function(){

    this.content.show(this.places_page);
    this.places_page.delegateEvents();
},

对我来说,这听起来不是最好的方法

您应该使用布局的区域管理器来显示视图,而不需要您定义的功能

我赞成这种方法

var view = new CustomView();
layout.content.show(view);`
随后:

var newView = new SecondCustomView();
layout.content.show(newView);
如果你想继续沿着你现在的路走下去,那么你最好使用这种方法:

initialize: function () {
    _.bindAll(this);
},
show_places_page: function () {
    var placesLayout = new Places_Layout();
    this.content.show(placesLayout);
}
这有意义吗

在没有看到更多的结构的情况下,很难提出最佳的行动方案

您在
initialize
中创建视图是否有原因?

Marionette(v.1)onwords使用Backbone.babbysitor管理子视图

在你的情况下,你也这样做。 只需创建一个容器来存储所有选项卡视图。稍后查询容器以返回需要显示的视图

this.tabViewsContainer = new Backbone.ChildViewContainer();
this.tabViewContainer.add(new CustomView(),'tab1');
this.tabViewContainer.add(new SecondCustomView(),'tab2');
要在以后显示视图,只需执行以下操作

var custv = container.findByCustom("tab1");
this.content.show(custv);
在关闭方法中,布局视图成功关闭容器中的所有视图

this.tabViewsContainer.each(function(view){view.close()});

您不必每次从一个选项卡切换到另一个选项卡时都创建布局/项目/组合/集合视图,相反,您可以按照现在的方式将内容保存在变量中,问题是每次要呈现内容时都会重新声明变量。 解决方案是,如果不将该变量附加到视图中,则必须验证该变量(this.places_页面)是否已声明,这样当您多次调用该变量时,它将保持相同的布局视图,而不会出现任何问题,只需注意,在呈现主视图(保存区域的视图)时,嵌套的子视图(在区域中)将丢失,直到新的导航通过它们

initialize: function(){
    _.bindAll(this);

    // You can asign a diferent variable for each view so when you call show_places_page it will render with the same view.

    if (!this.places_page){
         this.places_page   = new Places_Layout();
    }

    // other tab        
    if (!this.other_page){
         this.other_page   = new OtherPage_Layout();
    }

},

show_places_page: function(){

    this.content.show(this.places_page);
    this.places_page.delegateEvents();
},

您不应该在初始化中创建所有视图,因为这将导致内存泄漏,这就是为什么您应该动态创建视图的原因。我还建议创建一个通用函数,用于在内容区域中显示视图,以提高代码的可重用性。我建议您采用以下解决方案:

//define the regions of your layout view
regions: {
  content: '#content'
},
//Maintain a config for the tab content view classes.
contentViews: {
  tab1: Tab1View,
  tab2: Tab2View,
  tab3: Tab3View
},
//keeps all the view instances
viewInstances: {},
/*
 * show tab function is called when you click a tab item.
 * Consider each tab has a attribute for tab name.
 * For example HTML of your one tab is like:
 * <div data-tab-name="tab_name">Tab <tab_name></div> 
 */
showTab: function (e) {
  var tabName = $(e.currentTarget).attr("data-tab-name");
  /*
   * code for showing selected tab goes here...
   */

  //check and create the instance for the content view
  if (!this.viewInstances[tabName]) {
      this.viewInstances[tabName] = new this.contentViews[tabName]();
  }
  //Then here you are actually showing the content view
  this.content.show(this.viewInstances[tabName]);
  this.viewInstances[tabName].delegateEvents(); //this is to rebind events to the view.
}
//定义布局视图的区域
区域:{
内容:“#内容”
},
//维护选项卡内容视图类的配置。
内容视图:{
tab1:tab1视图,
tab2:Tab2View,
tab3:Tab3View
},
//保留所有视图实例
视图实例:{},
/*
*单击选项卡项时,将调用“显示选项卡”功能。
*考虑每个选项卡都有一个标签名的属性。
*例如,一个选项卡的HTML如下所示:
*标签
*/
显示选项卡:功能(e){
var tabName=$(e.currentTarget).attr(“数据选项卡名称”);
/*
*显示所选选项卡的代码位于此处。。。
*/
//检查并创建内容视图的实例
如果(!this.viewInstances[tabName]){
this.viewInstances[tabName]=新this.contentViews[tabName]();
}
//然后在这里您实际显示的是内容视图
this.content.show(this.viewInstances[tabName]);
this.viewInstances[tabName].delegateEvents();//这是将事件重新绑定到视图。
}

是的,我认为您应该在每次更改内容时创建一个新的复合视图,这是因为当您在某个区域上调用show方法时,它会注意关闭和解除绑定附加到该区域的任何旧视图。所以我认为,当你把它再次连接到该地区时,它错过了一些事件。。。