Skip to content

Instantly share code, notes, and snippets.

@belackriv
Last active December 1, 2015 16:35
Show Gist options
  • Save belackriv/23ff796a20ed213c152f to your computer and use it in GitHub Desktop.
Save belackriv/23ff796a20ed213c152f to your computer and use it in GitHub Desktop.
Marionette Transition Region Example
'use strict';
import TransitionRegion from './transitionRegion';
export default TransitionRegion.extend({
//can override transitionIn and transitionOut with diff effects
//must trigger 'transition:out:complete' and optionally 'transition:in:complete'
transitionOut(){
var region = this;
this.$el.effect({
effect: 'blind',
direction: 'right',
complete(){
region.trigger('transition:out:complete');
}
});
},
transitionIn(view){
var region = this;
this.$el.hide().effect({
effect: 'slide',
direction: 'left',
complete(){
region.trigger('transition:in:complete');
}
});
}
});
'use strict';
import _ from 'underscore';
import Marionette from 'marionette';
export default Marionette.Region.extend({
show: function(view, options) {
if (!this._ensureElement()) {
return;
}
this._ensureViewIsIntact(view);
Marionette.MonitorDOMRefresh(view);
var showOptions = options || {};
var isDifferentView = view !== this.currentView;
var preventDestroy = !!showOptions.preventDestroy;
var forceShow = !!showOptions.forceShow;
// We are only changing the view if there is a current view to change to begin with
var isChangingView = !!this.currentView;
// Only destroy the current view if we don't want to `preventDestroy` and if
// the view given in the first argument is different than `currentView`
var _shouldDestroyView = isDifferentView && !preventDestroy;
// Only show the view given in the first argument if it is different than
// the current view or if we want to re-show the view. Note that if
// `_shouldDestroyView` is true, then `_shouldShowView` is also necessarily true.
var _shouldShowView = isDifferentView || forceShow;
this._preTransitionOut(isChangingView, isDifferentView, options);
this.once('transition:out:complete', ()=>{
this._postTransitionOut(_shouldDestroyView, isChangingView, _shouldShowView);
if (_shouldShowView) {
this._preTransitionIn(view, isChangingView, options, showOptions);
this.once('transition:in:complete', ()=>{
this._postTransitionIn(view, isChangingView, options);
});
this.transitionIn();
}
});
this.transitionOut();
return this;
},
_preTransitionOut(isChangingView, isDifferentView, options){
if (isChangingView) {
this.triggerMethod('before:swapOut', this.currentView, this, options);
}
if (this.currentView && isDifferentView) {
delete this.currentView._parent;
}
},
_postTransitionOut(_shouldDestroyView, isChangingView, _shouldShowView){
if (_shouldDestroyView) {
this.empty();
// A `destroy` event is attached to the clean up manually removed views.
// We need to detach this event when a new view is going to be shown as it
// is no longer relevant.
} else if (isChangingView && _shouldShowView) {
this.currentView.off('destroy', this.empty, this);
}
},
_preTransitionIn(view, isChangingView, options, showOptions){
// We need to listen for if a view is destroyed
// in a way other than through the region.
// If this happens we need to remove the reference
// to the currentView since once a view has been destroyed
// we can not reuse it.
view.once('destroy', this.empty, this);
// make this region the view's parent,
// It's important that this parent binding happens before rendering
// so that any events the child may trigger during render can also be
// triggered on the child's ancestor views
view._parent = this;
this._renderView(view);
if (isChangingView) {
this.triggerMethod('before:swap', view, this, options);
}
this.triggerMethod('before:show', view, this, options);
Marionette.triggerMethodOn(view, 'before:show', view, this, options);
if (isChangingView) {
this.triggerMethod('swapOut', this.currentView, this, options);
}
// An array of views that we're about to display
var attachedRegion = Marionette.isNodeAttached(this.el);
// The views that we're about to attach to the document
// It's important that we prevent _getNestedViews from being executed unnecessarily
// as it's a potentially-slow method
var displayedViews = [];
var attachOptions = _.extend({
triggerBeforeAttach: this.triggerBeforeAttach,
triggerAttach: this.triggerAttach
}, showOptions);
if (attachedRegion && attachOptions.triggerBeforeAttach) {
displayedViews = this._displayedViews(view);
this._triggerAttach(displayedViews, 'before:');
}
this.attachHtml(view);
this.currentView = view;
if (attachedRegion && attachOptions.triggerAttach) {
displayedViews = this._displayedViews(view);
this._triggerAttach(displayedViews);
}
},
_postTransitionIn(view, isChangingView, options){
if (isChangingView) {
this.triggerMethod('swap', view, this, options);
}
this.triggerMethod('show', view, this, options);
Marionette.triggerMethodOn(view, 'show', view, this, options);
},
//can override transitionIn and transitionOut with diff effects
//must trigger 'transition:out:complete' and optionally 'transition:in:complete'
transitionOut(){
this.trigger('transition:out:complete');
},
transitionIn(view){
this.trigger('transition:in:complete');
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment