Prerendered Content
View classes can be initialized with pre-rendered DOM.
This can be HTML that's currently in the DOM:
import { View } from 'backbone.marionette';
const myView = new View({ el: $('#foo-selector') });
myView.isRendered(); // true if '#foo-selector` exists and has content
myView.isAttached(); // true if '#foo-selector` is in the DOM
Or it can be DOM created in memory:
import { View } from 'backbone.marionette';
const $inMemoryHtml = $('<div>Hello World!</div>');
const myView = new View({ el: $inMemoryHtml });
In both of the cases at instantiation the view will determine its state as to whether the el is rendered or attached.
Note render
and attach
events will not fire for the initial state as the state is set already at instantiation and is not changing.
Managing View
children
With View
in most cases the render
event is the best place to show child views for best performance.
However with pre-rendered DOM you may need to show child views in initialize
as the view will already be rendered.
import { View } from 'backbone.marionette';
import HeaderView from './header-view';
const MyBaseLayout = View.extend({
regions: {
header: '#header-region',
content: '#content-region'
},
el: $('#base-layout'),
initialize() {
this.showChildView('header', new HeaderView());
}
});
Managing a Pre-existing View Tree.
It may be the case that you need child views of already existing DOM as well. To set this up you'll need to query for el
s down the tree:
import { View } from 'backbone.marionette';
import HeaderView from './header-view';
const MyBaseLayout = View.extend({
regions: {
header: '#header-region',
content: '#content-region'
},
el: $('#base-layout'),
initialize() {
this.showChildView('header', new HeaderView({
el: this.getRegion('header').$el.contents()
}));
}
});
The same can be done with CollectionView
:
import { CollectionView } from 'backbone.marionette';
import ItemView from './item-view';
const MyList = CollectionView.extend({
el: $('#base-table'),
childView: ItemView,
childViewContainer: 'tbody',
buildChildView(model, ChildView) {
const index = this.collection.indexOf(model);
const childEl = this.$('tbody').contents()[index];
return new ChildView({
model,
el: childEl
});
}
});
const myList = new MyList({ collection: someCollection });
// Unlike `View`, `CollectionView` should be rendered to build the `children`
myList.render();
https://github.com/marionettejs/backbone.marionette/issues/3128
Re-rendering children of a view with preexisting DOM.
You may be instantiating a View
with existing HTML, but if you re-render the view, like any other view, your view will render the template
into the view's el
and any children will need to be re-shown.
So your view will need to be prepared to handle both scenarios.
import _ from 'underscore';
import { View } from 'backbone.marionette';
import HeaderView from './header-view';
const MyBaseLayout = View.extend({
regions: {
header: '#header-region',
content: '#content-region'
},
el: $('#base-layout'),
initialize() {
this.showChildView('header', new HeaderView({
el: this.getRegion('header').$el.contents()
}));
},
template: _.template('<div id="header-region"></div><div id="content-region"></div>'),
onRender() {
this.showChildView('header', new HeaderView());
}
});
© 2017 Muted Solutions, LLC
Licensed under the MIT License.
https://marionettejs.com/docs/v4.0.0/dom.prerendered.html