As you learned in the previous post, you learned how you can load templates inline in your app using RequireJS. The next step is to load and compile a template file. And for your offline app, learn how you can cache templates. Caching saves a round trip to the server, making your application incredibly responsive.
In this tutorial we will compile, load, and cache LoDash (or Underscore) templates and then use those templates to transform data in our single page app.
The technique uses RequireJS, so there is no more dynamic loading. Templates are bundled within your code which saves some HTTP requests.
Getting Started
For this project, you will need LoDash (or Underscore), and RequireJS. For this tutorial, the files are all in Scripts folder.You can get the libraries from their websites or for your Visual Studio project from NuGet.
Next, create a template named productsTmpl.html in a Templates folder:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<ul> | |
<% _.forEach(products, function(product) { %> | |
<li> | |
<strong><%- product.name %></strong> | |
<span>( Cateogry: <span class="value"><%- product.category %></span> )</span> | |
</li> | |
<% }); %> | |
</ul> |
Next, create an HTML page that contains a reference to required.js. Note that the starting point for will on the page for simplicity, but in real life you would put the code into an main.js or app.js file (and some file references would change when you do that).
Setup the Page
In this page, you should also set requirejs.config to point to the Scripts folder as the RequireJs baseUrl and also map the paths for using _ . You can also map the use of underscore to lodash. The file name does not really matter, but take note, because later you will use the filename in the AppCache.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>Load Text Template</title> | |
</head> | |
<body> | |
<script src='require.js'></script> | |
<script> | |
requirejs.config({ | |
baseUrl: 'Scripts', | |
paths: { | |
"_": "Scripts/lodash" | |
}, | |
map: { | |
'*': { 'underscore': 'lodash' } | |
} | |
}); | |
// Your code goes here | |
</script> | |
</body> | |
</html> |
For more information on setting up require.js, see Using RequireJS Asynchronous Module Definition (AMD) Modules with jQuery, LoDash.
DomReady
You may find that RequireJS loads scripts before the DOM is ready.
The domReady module implements a cross-browser way to determine when the DOM is ready. Download the domReady Require module directly from the RequireJS site, click the Download button and copy and paste the code into a file named domready.js in the Scripts folder.
You will use it as one of your dependencies.
Text PlugIn
The key to using a file as a dependency is using Require’s Text.js plugin. Great for loading templates or other HTML files.
The plugin tells Require.js to load text files and treat them as dependencies when RequireJS see text! as the prefix of a dependency.
Get the plugin from The Require Text.js Plugin on GitHub and put it in the Scripts folder.
Your files should look similar to this:
Loading Template Script
The add the following code to the script:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require(['underscore', 'text!../Templates/productsTmpl.html', 'domReady!'], | |
function (_, productsTemplate) { | |
var productsData = [{ name: 'Action Figure', category: 'Toy' }, | |
{ name: 'Bicycle', category: 'Transportation' }]; | |
var output = _.template(productsTemplate, { products: productsData }); | |
document.body.innerHTML = output; | |
} | |
); |
underscore will be resolved using the map lodash.js that is in the baseUrl. domReady is a RequireJS plugin which requires the !.
To load the file as a dependency, you designate:
- The text plugin using the text! prefix
- The path to the file begins at the baseUrl
- Specify the .html suffix.
require() second parameter returns with the return values each item in the required array. For from underscore, you get _ . From the template, you get the text of productsTmpl/html that you set to the variable named productsTemplate.
Next, you:
- Create some data.
- Render the template with the data.
- Apply the output to the body tag.
For more information on the template rendering works, see HTML Templates With Logic Using Underscore, LoDash.
Restrictions on XHR
The text plugin works by using XMLHttpRequest (XHR) to fetch the text for the resources it handles.
- Many browsers do not allow file:// access to just any file.
- There are restrictions for using XHR to access files on another web domain – not all browsers support CORS.
If you need to go across domains, when the text plugin determines that the request for the resource is on another domain, it will try to access a “.js” version of the resource by using a script tag. Script tag GET requests are allowed across domains.
A .js version of the resource should just be a script with a define() call in it that returns a string for the module value.
For an example, see the documentation on Require Text.js Plugin on GitHub.
Optimization
If you use the Require.js optimizer, you can make the text strings inline. the RequireJS optimizer will inline any text! references with the actual text file contents into the modules, so after a build, the modules that have text! dependencies can be used from other domains.
For more details, see the RequireJS documentation.
Caching Templates Using AppCache
Next, we want to be able to cache the templates and use them for users who are disconnected. We will first use AppCache to do this.
You need to be sure your web server will serve .appcache files as the text/cache-manifest
Mime type. For more details see, 23.1 – AppCache for Offline Apps.
NOTE: For development in Visual Studio, you may need to also need to change your IIS Server so you will no longer use IIS Express. Right-click your solution, click Properties. Click Web. Clear Use IIS Express checkbox.
Next, create a new file named products.appcache and put it in the same directory as your html file (the root). As you learned in earlier posts, the AppCache has a particular format, beginning with CACHE MANIFEST, then CACHE and a list of files. You can also add
List each of the files that your app will need to run should it be offline. In this case, we add each of the script files, the template file and your html file. As best practice, also include a comment with the date that you can use when you want to update your cache.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CACHE MANIFEST | |
# 2013-07-31 | |
CACHE: | |
Scripts/tmpl.js | |
Scripts/require.js | |
Scripts/text.js | |
Scripts/domReady.js | |
Scripts/lodash.js | |
Templates/productsTmpl.html | |
YourHtmlFileName.html |
Finally, add the manifest attribute to your html tag.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html manifest="products.appcache"> |
The first time you run, you will get the template from server. Following times, you will get the files from the AppCache on the client.
While developing, you will want to clear or change the cache. You can:
- Delete the manifest file, which should cause the AppCache to be deleted the next time the browser attempts to update.
- Change the date (or version number) in the comment.
For more information, see AppCache for Offline Apps.
Sample Code
Samples for this project are available in the DevDays GitHub: https://github.com/devdays/single-page-app/tree/master/LoadTemplates
This project uses 2-LoadEverythingWithAppCache.html
One thought on “Single Page App – Loading, Caching LoDash or Underscore Templates Using RequireJS, AppCache”
Comments are closed.