-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.js
194 lines (151 loc) · 6.4 KB
/
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
// main.js
require( [
'jquery',
'underscore',
'backbone',
'handlebars',
'marionette',
'backbone.declarative.views',
'precompiled.templates',
'marionette.handlebars'
], function ( $, _, Backbone, Handlebars ) {
var domView, precompiledView, lazyLoadedView, lazyLoadedPrecompiledView,
Marionette = Backbone.Marionette,
$container = $( ".content" ),
MarionetteView = Marionette.ItemView || Marionette.View,
BaseView = MarionetteView.extend( {
tagName: "p"
} );
// Allow lazy loading of compiled templates
Backbone.Marionette.TemplateCache.allowCompiledTemplatesOverHttp = true;
// Expose Handlebars as a browser global. Makes lazy-loading of *compiled* templates possible.
//
// See explanation in require-config.js. By contrast, raw HTML templates (ie strings, not code) can be lazy-loaded
// without a global.
window.Handlebars = Handlebars;
// Implement a lazy template loader.
_.extend( Backbone.Marionette.TemplateCache.prototype, {
isPrecompiled: function ( templateId ) {
return templateId.substr( -3 ) === ".js";
},
getTemplateUrl: function ( templateId, options ) {
var isPrecompiled = this.isPrecompiled( templateId ),
versionInfix = isLegacyHandlebars() ? "legacy" : "modern",
prefix = isPrecompiled ? "templates/precompiled/" + versionInfix + "/non-amd/" : "templates/raw/",
suffix = isPrecompiled ? "" : ".hbs";
return prefix + templateId + suffix;
},
lazyLoadTemplate: function ( templateId, options ) {
var templateHtml, compiledTemplate,
isPrecompiled = this.isPrecompiled( templateId ),
templateUrl = this.getTemplateUrl( templateId, options );
if ( isPrecompiled ) {
this.loadResource( { url: templateUrl, isJavascript: true } );
// The $.ajax call returns a precompiled template as a string, not as Javascript code. We simply throw
// the string away.
//
// But the code has also been executed, which means that it has been added to the Handlebars cache. We
// must read it from the cache now.
//
// Our template IDs for precompiled templates end in ".js" because we needed to fetch the actual files.
// In the Handlebars cache, the ".js" file extension not part of the ID. We need to remove it before
// querying the cache.
templateId = templateId.slice( 0, -3 );
compiledTemplate = this.getPrecompiledTemplate( templateId );
} else {
// Loading a raw HTML template (ie, a string).
templateHtml = this.loadResource( { url: templateUrl, isJavascript: false } );
}
return templateHtml || compiledTemplate;
},
loadResource: function ( config ) {
var content;
Backbone.$.ajax( {
url: config.url,
success: function ( data ) { content = data; },
async: false,
cache: true,
dataType: config.isJavascript ? "script" : "text"
} );
return content;
}
} );
// Load templates in various ways
// Load a template from the DOM.
//
// The el is defined by the template in this case, using Backbone.Declarative.Views. Hence, we use a plain ItemView
// (or View, in Marionette 3), rather than the local BaseView which also defines the el.
domView = new MarionetteView( {
model: new Backbone.Model( { origin: "DOM-based" } ),
template: "#dom-template"
} );
// Load a precompiled template
precompiledView = new BaseView( {
model: new Backbone.Model( { origin: "precompiled" } ),
template: "precompiled"
} );
// Lazy-load a template
lazyLoadedView= new BaseView( {
model: new Backbone.Model( { origin: "lazy-loaded" } ),
template: "lazy-loaded"
} );
// Lazy-load a template asynchronously
createViewWithAsyncTemplate( {
ViewClass: BaseView,
model: new Backbone.Model( { origin: "lazy-loaded" } ),
templateId: "lazy-loaded-async"
} );
// Lazy-load a precompiled template
lazyLoadedPrecompiledView = new BaseView( {
model: new Backbone.Model( { origin: "lazy-loaded" } ),
template: "lazy-loaded-precompiled.js"
} );
// Lazy-load a precompiled template async
createViewWithAsyncTemplate( {
ViewClass: BaseView,
model: new Backbone.Model( { origin: "lazy-loaded" } ),
templateId: "lazy-loaded-precompiled-async.js"
} );
// Show the synchronous views (the async ones have been handled inside createViewWithAsyncTemplate()).
addHeadline( "Preloaded" );
show( domView );
show( precompiledView );
addHeadline( "Lazy-loaded" );
show( lazyLoadedView );
show( lazyLoadedPrecompiledView );
addHeadline( "Async lazy-loaded" );
function addHeadline ( text ) {
$( "<h2/>" ).text( text ).wrapInner( "<small/>").appendTo( $container );
}
function show ( view ) {
view.render();
view.$el.appendTo( $container );
}
function preloadTemplate ( templateId, deferred ) {
Marionette.TemplateCache.get( templateId );
deferred.resolve();
}
function createViewWithAsyncTemplate ( config ) {
// Preload the template before using it in a view. Do it async. Delay the creation of the view until the
// template has arrived in the cache.
//
// The templateLoaded promise triggers view creation. The helper function preloadTemplate() receives the promise
// and resolves it when the template is ready.
var templateLoaded = new Backbone.$.Deferred( function ( deferred ) {
setTimeout( _.partial( preloadTemplate, config.templateId, deferred ), 0 );
} );
templateLoaded.done( function () {
var view = new config.ViewClass( {
model: config.model,
template: config.templateId
} );
show( view );
} );
}
function getHandlebarsVersion () {
return +Handlebars.VERSION[0]
}
function isLegacyHandlebars () {
return getHandlebarsVersion() < 4;
}
} );