As you know there are several Visual Studio Templates which gives a quick start for your SPA development. If you are like me, then you want to know what is the plumbing code for the SPA development. In this blog I will give you step by step instructions on building a Durandal SPA application using any Visual Studio Templates
Before we start, we need all the dependencies of our application. Download all the below dependencies from their websites
In addition we also need couple of nuget packages. Which we will download while setting up the project.
Once all the necessary scripts files are downloaded, let’s fire up Visual studio. Below are the steps we need to follow to create a Visual Studio durandal project
- Create MVC Empty project
- Create Content & Scripts Folder
- User Scripts create Durandal and copy all the files downloaded from durandal under js. Include them in the solution
- Again under Scripts Create foundation and copy the scripts from zurb foundation and include them in the solution
- Copy Knockout under scripts folder, similarly copy jquery, require, text
- Under content copy durandal.css, foundation.css, normalize.css
- Under content create app.css which is used by our SPA
- In the root project create folder App & under it create viewmodels & views. This is where we will keep all our SPA scripts
- Under App_Start create BundleConfig.cs which will include the bundle configuration for all the javascripts and css.
- Install the Nuget package: Install-Package Microsoft.AspNet.Web.Optimization
- Include the following code in the BundleConfig.cs
public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(
new ScriptBundle("~/scripts/libraries")
.Include("~/scripts/jquery-{version}.js")
.Include("~/scripts/knockout-{version}.js")
.Include("~/scripts/knockout.validation.js")
.Include("~/scripts/knockout.viewmodel.js")
.Include("~/scripts/foundation/foundation.js")
.IncludeDirectory("~/scripts/foundation", "*.js")
);
bundles.Add(
new StyleBundle("~/content/css")
.Include("~/content/normalize.css")
.Include("~/content/foundation.css")
.Include("~/content/durandal.css")
.Include("~/content/app.css")
);
}
}
· In the global.asax on the Application_Start initialize the bundle config
BundleConfig.RegisterBundles(BundleTable.Bundles);
- Add Home Controller
- Add a view without using layout page option and use the below code
@using System.Web.Optimization
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>My First SPA</title>
@Styles.Render("~/Content/css")
</head>
<body class="main">
<div id="applicationHost">
<div class="splash">
Page loading ...
</div>
</div>
@Scripts.Render("~/scripts/libraries")
<script src="~/Scripts/require.js" data-main="@Url.Content("~/App/main")"></script>
</body>
</html>
With this we are done with MVC setup. Now we need to create the javascript files
- Create main.js which is starting point for Durandal and include the below code
//require configuration for durandal
require.config({
paths: {
'text': '../Scripts/text',
'durandal': '../Scripts/durandal',
'plugins': '../Scripts/durandal/plugins',
'transitions': '../Scripts/durandal/transitions'
}
});
//defining global libraries
define('jquery', function () { return jQuery; });
define('knockout', ko);
//starting the app
define(['durandal/system', 'durandal/app', 'durandal/viewLocator', 'durandal/composition'], function (system, app, viewLocator, composition) {
app.title = 'Hello World';
//specify which plugins to install and their configuration
app.configurePlugins({
router: true,
});
app.start().then(function () {
//Replace 'viewmodels' in the moduleId with 'views' to locate the view.
//Look for partial views in a 'views' folder in the root.
viewLocator.useConvention();
//Show the app by setting the root view model for our application.
app.setRoot('viewmodels/shell', 'entrance');
});
});
- Create shell.js & shell.html under viewmodels & viewfolders. Shell is like a layout page in MNC and include the below code
o shell.js
define(['plugins/router'], function (router) {
return {
activate: activate,
router: router
};
function activate() {
var routes = [
{ route: ['', 'home'], moduleId: 'home', title: 'Home' },
];
router.makeRelative({ moduleId: 'viewmodels' }) // router will look here for viewmodels by convention
.map(routes) // Map the routes
.buildNavigationModel() // Finds all nav routes and readies them
.activate(); // Activate the router
}
});
o shell.html
<div>
<h1>Title</h1>
<br />
<div class="content"
data-bind="router: { transition: 'entrance', cacheViews: true }"></div>
</div>
- Finally define home.js and & home.html. This is like an index page in MVC
o home.js
define([], function () {
var vm = {
activate: activate
};
return vm;
function activate() {
return true;
};
});
o home.html
<div>
Hello World!
</div>