Backbone Marionette Region show without render

2020-05-04 06:01发布

Is it possible to put a view that is already rendered into a backbone marionette region without rendering it again?

For example:

region.show(myView); // This will call render on myView

I don't want the region to render my view again.

If I do:

region.attachView(myView); // This won't render myView, but it also won't show it

2条回答
贼婆χ
2楼-- · 2020-05-04 06:24

First override marionette ItemView constructor and render like this (if you want to use it in CollectionView and CompositeView override these methods of them too):

var fnCons = Marionette.ItemView.prototype.constructor,
    fnRender = Marionette.ItemView.prototype.render;
Marionette.ItemView.prototype.constructor = function(){
  this.firstRender = true;
  fnCons.apply(this,arguments);       
}

Marionette.ItemView.prototype.render = function(){
  this.firstRender = false;
  fnRender.apply(this,arguments);
}

And then just override default region#show, if view is view.firstRender is true it's not rendered yet and must render it, else no action required.

Marionette.Region.prototype.show = function(view){    
  this.ensureEl();

  var isViewClosed = view.isClosed || _.isUndefined(view.$el);

  var isDifferentView = view !== this.currentView;

  if (isDifferentView) {
    this.close();
  }
  // These lines changed from default marionette action
  if(view.firstRender){
    view.render();
  }else{
    // Don anything else!
  }
  // End of overrided code


  if (isDifferentView || isViewClosed) {
    this.open(view);
  }

  this.currentView = view;

  Marionette.triggerMethod.call(this, "show", view);
  Marionette.triggerMethod.call(view, "show");
}

Edit

The solution above works fine, another way is (this will assume that view is rendered) :

Marionette.Region.prototype.showWithoutRender = function(view){
  this.ensureEl();

  var isViewClosed = view.isClosed || _.isUndefined(view.$el);
  var isDifferentView = view !== this.currentView;

  if (view !== this.currentView) {
    this.close();
  }

  if(isViewClosed || isDifferentView){
    this.open(view);
  }
  this.currentView = view;

  Marionette.triggerMethod.call(this, "show", view);
  Marionette.triggerMethod.call(view, "show");
}
查看更多
孤傲高冷的网名
3楼-- · 2020-05-04 06:37
// assume your view is already rendered
region.ensureEl();
region.open(myView);

this is not recommend though, use region.show(myView) if you can. Since it's gonna close the previous view to clean up all the event listeners, etc...

查看更多
登录 后发表回答