Hot Towel SPA – Visual Studio Project Template
posted by John with 177 comments
Want to build a SPA but can’t decide where to start? Use Hot Towel and in seconds you’ll have a SPA and all the tools you need to build on it! You can get Hot Towel along with the new RTM version of ASP.NET and Web Tools 2012.2, as announced by Scott Guthrie today.
Download the VSIX for the Hot Towel SPA template here
Hot Towel: Because you don’t want to go to the SPA without one!

Hot Towel creates a great starting point for building a Single Page Application (SPA) with ASP.NET. Out of the box you it provides a modular structure for your code, view navigation, data binding, rich data management and simple but elegant styling. It provides everything you need to build a SPA, so you can focus on your app, not the plumbing.
Learn more about building a SPA from my videos, tutorials and Pluralsight courses.
Create a New SPA Template Project with Hot Towel
Requirements:
- Visual Studio 2012 or Visual Studio Express 2012 for Web
- ASP.NET Web Tools 2012.2 update. You can install the update here.
Start Visual Studio and select New Project from the Start page. Or, from the File menu, select New and then Project.
In the Templates pane, select Installed Templates and expand the Visual C# node. Under Visual C#, select Web. In the list of project templates, select ASP.NET MVC 4 Web Application. Name the project and click OK.

In the New Project wizard, select Single Page Application.
Application Structure
Hot Towel SPA provides an App folder which contains the JavaScript and HTML files that define your application.
Inside the App folder:

The App folder contains a collection of modules. These modules encapsulate functionality and declare dependencies on other modules. The views folder contains the HTML for your application and the viewmodels folder contains the presentation logic for the views (a common MVVM pattern). The services folder is ideal for housing any common services that your application may need such as HTTP data retrieval or local storage interaction. It is common for multiple viewmodels to re-use code from the service modules.
ASP.NET MVC Server Side Application Structure
Hot Towel builds on the familiar and powerful ASP.NET MVC structure.
- App_Start
- Content
- Controllers
- Models
- Scripts
- Views
Featured Libraries
- ASP.NET MVC
- ASP.NET Web API
- ASP.NET Web Optimization – bundling and minification
- Breeze.js – rich data management
- Durandal.js – navigation, app life cycle and View composition
- Knockout.js – data bindings
- Require.js – Modularity with AMD and optimization
- Toastr.js – pop-up messages
- Twitter Bootstrap – robust CSS styling
Installing via the Visual Studio 2012 Hot Towel SPA Template
Hot Towel can be installed as a Visual Studio 2012 template. Just click File | New Project and choose ASP.NET MVC 4 Web Application. Then select the Hot Towel Single Page Application template and run!
Installing via the NuGet Package
Hot Towel is also a NuGet package that augments an existing empty ASP.NET MVC project. Just install using Nuget and then run!

How Do I Build On Hot Towel?
Simply start adding code!
- Add your own server-side code, preferably Entity Framework and WebAPI (which really shine with Breeze.js)
- Add views to the
App/viewsfolder - Add viewmodels to the
App/viewmodelsfolder - Add HTML and Knockout data bindings to your new views
- Update the navigation routes in
shell.js
Walkthrough of the HTML/JavaScript
Views/HotTowel/index.cshtml
index.cshtml is the starting route and view for the MVC application. It contains all the standard meta tags, css links, and JavaScript references you would expect. The body contains a single <div> which is where all of the content (your views) will be placed when they are requested. The @Scripts.Render uses Require.js to run the entrance point for the application’s code, which is contained in the main.js file. A splash screen is provided to demonstrate how to create a splash screen while your app loads.
<body>
<div id="applicationHost">
@Html.Partial("_splash")
</div>
@Scripts.Render("~/scripts/vendor")
<script type="text/javascript"
src="~/App/durandal/amd/require.js"
data-main="@Url.Content("~/App/main")"></script>
</body>
App/main.js
The main.js file contains the code that will run as soon as your app is loaded. This is where you want to define your navigation routes, set your start-up views, and perform any setup/bootstrapping such as priming your application’s data.
The main.js file defines several of durandal’s modules to help the application kick-start. The define statement helps resolve the modules dependencies so they are available for the function. First the debugging messages are enabled, which send messages about what events the application is performing to the console window. The app.start code tells the durandal framework to start the application. The conventions are set so that durandal knows all views and viewmodels are contained in the same named folders, respectively. Finally, the app.setRoot kicks loads the shell using a predefined entrance animation.
define(['durandal/app',
'durandal/viewLocator',
'durandal/system',
'durandal/plugins/router'],
function (app, viewLocator, system, router) {
// Enable debug message to show in the console
system.debug(true);
app.start().then(function () {
router.useConvention();
viewLocator.useConvention();
//Show the app by setting the root view
// model for our application.
app.setRoot('viewmodels/shell', 'entrance');
});
});
Views
Views are found in the App/views folder.
shell.html
The shell.html contains the master layout for your HTML. All of your other views will be composed somewhere in side of your shell view. Hot Towel provides a shell with three such regions: a header, a content area, and a footer. Each of these regions is loaded with contents form other views when requested.
The compose bindings for the header and footer are hard-coded in Hot Towel to point to the nav and footer views, respectively. The compose binding for the section #content is bound to the router module’s active item. In other words, when you click a navigation link its corresponding view is loaded in this area.
<div>
<header>
<!--ko compose: {view: 'nav'} --><!--/ko-->
</header>
<section id="content" class="main container-fluid">
<!--ko compose: {model: router.activeItem,
afterCompose: router.afterCompose,
transition: 'entrance'} -->
<!--/ko-->
</section>
<footer>
<!--ko compose: {view: 'footer'} --><!--/ko-->
</footer>
</div>
nav.html
The nav.html contains the navigation links for the SPA. This is where the menu structure can be placed, for example. Often this is data bound (using Knockout) to the router module to display the navigation you defined in the shell.js. Knockout looks for the data-bind attributes and binds those to the shell viewmodel to display the navigation routes and to show a progressbar (using Twitter Bootstrap) if the router module is in the middle of navigating from one view to another (see router.isNavigating).
<nav class="navbar navbar-fixed-top">
<div class="navbar-inner">
<a class="brand" href="/">
<span class="title">Hot Towel SPA</span>
</a>
<div class="btn-group"
data-bind="foreach: router.visibleRoutes">
<a data-bind="css: { active: isActive },
attr: { href: hash },
text: name"
class="btn btn-info" href="#"></a>
</div>
<div class="loader pull-right"
data-bind="css: { active: router.isNavigating }">
<div class="progress progress-striped
active page-progress-bar">
<div class="bar" style="width: 100px;"></div>
</div>
</div>
</div>
</nav>
home.html and details.html
These views contain HTML for custom views. When the home link in the nav view’s menu is clicked, the home view will be placed in the content area of the shell view. These views can be augmented or replaced with your own custom views.
footer.html
The footer.html contains HTML that appears in the footer, at the bottom of the shell view.
ViewModels
ViewModels are found in the App/viewmodels folder.
shell.js
The shell viewmodel contains properties and functions that are bound to the shell view. Often this is where the menu navigation bindings are found (see the router.mapNav logic).
define(['durandal/system',
'durandal/plugins/router',
'services/logger'],
function (system, router, logger) {
var shell = {
activate: activate,
router: router
};
return shell;
function activate() {
return boot();
}
function boot() {
router.mapNav('home');
router.mapNav('details');
log('Hot Towel SPA Loaded!', null, true);
return router.activate('home');
}
function log(msg, data, showToast) {
logger.log(msg,
data,
system.getModuleId(shell),
showToast);
}
});
home.js and details.js
These viewmodels contain the properties and functions that are bound to the home view. it also contains the presentation logic for the view, and is the glue between the data and the view.
define(['services/logger'],
function (logger) {
var vm = {
activate: activate,
title: 'Home View'
};
return vm;
function activate() {
logger.log('Home View Activated',
null, 'home', true);
return true;
}
});
Services
Services are found in the App/services folder. Ideally your future services such as a dataservice module, that is responsible for getting and posting remote data, could be placed.
logger.js
Hot Towel provides a logger module in the services folder. The logger module is ideal for logging messages to the console and to the user in pop up toasts.
Resources
- SPA Resources
- Hot Towel on GitHub
- Hot Towel for ASP.NET MVC on NuGet

- Hot Towelette for ASP.NET (no MVC required) on NuGet


Nik Ivancic on said:
John your timing could not be better – as I was precisely the guy who looked ad so many different alternatives for SPA that finally I could not decide where to start.
Richard B on said:
Very kool. I’ll grab my hot towel and jump right in
Peter on said:
Does JS Intellisense work out of the box. I’ve been unsuccessful trying to get Intellisense working with a CodeCamper Breeze based project, as RequireJS is a stumbling block.
John on said:
Peter – Generally, JavaScript intellisense works best with a _references.js file in the scripts folder. That file should contain references to the scripts you want intellisense for. You can google this for the exact syntax. I also use Resharper, which provides intellisense for JS too.
Mike on said:
The problem is Intellisense doesn’t work inside the modules. So for instance accessing the logger inside a new view service that also uses require.js.
Like a data service that looks like this.
define(['services/logger'], function (logger) {
// Intellisense doesn’t work here for logger or anything else that loads as a require.js module.
});
Peter on said:
Mike is exactly right. _references.js is fine for global references, but cant understand RequireJS. I spent some time trying to get this to work on CodeCamper, with no real success.
My research found
http://stackoverflow.com/questions/10167621/javascript-amd-modules-how-to-get-visual-studio-intellisense-across-modules
http://social.msdn.microsoft.com/Forums/en-US/toolsforwinapps/thread/10238344-d17c-47ea-9248-13a43ca10711/
http://www.codeproject.com/Articles/460836/Making-the-most-out-of-JavaScript-Intellisense-in
First change would be to use named modules, not anonymous.
Unfortunately I’m having bigger challenges with Durandal & Ko.subscriptions at the moment.
Nik Ivancic on said:
Is there a way to set the length of time the splash screen is up. I would expect that the current behavior is such that the splash screen goes away when the app is loaded, which on a quick machine and relatively small app looks like a flash, not splash
John on said:
Nik – Hmmm. If you really want to control the first screen, you could do that with Durandal in its boot sequence. Or if you want the splash.html to start and hang around for a set amount of time, you could delay the kick off of durandal using a settimeout. I havent tried it, but that could work.
Nik Ivancic on said:
Thanks, John; I will try that route and will post my findings – in case you want to add such information to http://www.johnpapa.net/hottowel article.
By the way, I built my first HotTowel app, love the name, love the template and plan to make a SPA prototype of Congral’s Shared Care Space application – see http://www.sharedcareplan.org which is a Patient Portal Component of SCS.
l3ny on said:
Why does everything has be MVC now days. That’s unfair.
John on said:
l3ny – You can use HotTowelette with ASP.NET (non MVC) . Its a NuGet package that is a little sister to HotTowel. Grab HotTowelette here
Markus Zywitza on said:
I’ve been wondering whether the template also includes authentication and authorization. I’ve been missing that in the Code Camper SPA and the Pluralsight course.
John on said:
Markus – The ASP.NET SPA template has auth built in, definitely check it out!
Paul on said:
Howdy John and thanks for this awesome template. Just wondering…. how would one go about a heiracial NAV using routes?
router.mapNav(‘home’)
router.mapNav(‘bedroom’);
router.mapNav(‘details’);
John on said:
Paul – You can define nested navigation using slashes in the paths.
Paul on said:
Thanks John. I have nested routes working in ‘shell.js’ i.e. router.mapNav(‘admin/dashboard’, null, ‘Dashboard’);
but I would like the NAV to display sub menus for nested routes i.e.
Home
Details
Admin
|—Dashboard
Any thoughts on how to achieve this?
John on said:
Paul,
You can create custom menus. For example, you could create a sub menu in a dropdown button for an about view (and other additional sub items)
var routes = [{ url: 'about', moduleId: 'viewmodels/about', name: 'About', visible: false, caption: 'About', // Add anything you want to settings settings: { admin: true } }]; router.map(routes);Then you can add buttons with a binding like this (wrapped in a ul with bootstrap):
< a class="btn btn-info dropdown-toggle" data-toggle="dropdown" rel="nofollow"> <span>Admin</span> <span class="caret"></span></a> <ul class="dropdown-menu pull-right"> <!-- ko foreach: adminRoutes --> <li><a data-bind="attr: { href: hash }, html: caption" rel="nofollow"></a></li> <!-- /ko --> </ul>You can find much more in my upcoming Pluralsight course, SPA JumpStart, due out in March 2013
Dirk on said:
Way to get toastr included!
Naze on said:
Hi John, I been following your SPA work on pluralsight and I’ve been really impressed. Can you recommend a treegrid control that will work with knockout bindings in a SPA application.
John on said:
Naze – I am not aware of any treeview controls that I would recommend at this point. Perhaps check out Kendo UI
76Foxtrot on said:
I’ve used a css3 treeview with knockout and it seems to work pretty well.
Have a look at http://acidmartin.wordpress.com/2011/09/26/css3-treevew-no-javascript/
Dave on said:
Can you post some sample code?
Thanks
cipo on said:
Does anyone has sample app (something simple which includes webapi controller and breeze) which is based on hot towel spa template?
John on said:
cipo – The Breeze SPA template has a web api controller built into it. You can copy that over from the ToDo app.
Erikas on said:
John,
Will HotTowelSpa.vsix installer support Microsoft Visual Studio Express 2012 for Web? Right now it’s not installing the template:
19/02/2013 15:00:03 – Searching for applicable products…
19/02/2013 15:00:03 – Found installed product – Microsoft Visual Studio 2010 Ultimate
19/02/2013 15:00:03 – Found installed product – Microsoft Visual Studio Express 2012 for Web
19/02/2013 15:00:03 – Found installed product – Global Location
19/02/2013 15:00:03 – VSIXInstaller.NoApplicableSKUsException: This extension is not installable on any currently installed products.
John on said:
Erikas – The template doe snot support Web Express today, however this will be changed later this week. Sorry for the delay.
Prashanth on said:
And I am really waiting for your next course on Pluralsight (From scratch – for a JS rookie like me)
jomarito on said:
Hi, a very interesting post.
I’ve tried but adding hottowel with nuget to a new mvc4 app it doesn’t work. http request for /script/vendor returns 404 error, not loading needed scripts.
What can be happening?
Other question, vsix is only availble for visual studio 2012 and not for express edition, is it ok?
Thanks and regards.
Pheenix on said:
Could you please provide an example for the details.html with a binding in it?
Probably I don’t understand it completely, but it would help me to.
I extended the details.js viewmodel(vm) with a something: “something” and I would like to bind it in the details.html as follows: .
data-bind=”text: something”
It is also a bit disturbing that throughout changing these html files it is always cached in the browser, and I couldn’t find a good way for having the new contents. I always have to clear cache…
John on said:
Pheenix,
Sure. The details.js viewmodel already has a simple binding in it for the title.
var vm = { activate: activate, title: 'Details View' };So what you did should work just fine. And you could add some more like this with or without observables:
var vm = { activate: activate, title: 'Details View', something: 'some value', foo: ko.observable('hello world') };The way I handle caching is to check the box for
disable cachein Chrome. Then keep the developer tools open and every time I browse to a page I refresh first. This keeps it fresh. If you are not sure if your changes applied because of cache, you can always check the sources tab and examine the javascript file to see what is in there.Hope this helps.
JoeBloke on said:
In Chrome, when you have the developer tools open, you can also click refresh, but hold it in for a second or two. You’ll see a dropdown menu with nice Reload options.
Eric on said:
After watching and digesting the SPA course on Pluralsight, I had been using the CodeCamper “framework” to build SPA’s. This is an awesome time saver!!!
Jason on said:
Hey John, Thanks for this great article and as always your great work in the community!
Quick question – any ideas why none of the templates are showing up for me after installation? I restarted VS as well as rebooted. I still see the plain stock list of web project templates (MVC3, MVC4, etc). New Project -> Visual C# -> Web -> (same list).
Thanks!!
Jason on said:
Duh ignore me!! I didnt realize I had to select MVC4 project and THEN i see the list of templates.
Thanks again!!
Nat on said:
Marvellous! John, have you considered doing a Hot Towel specific course for Pluralsight?
Mladen Mihajlovic on said:
Any chance of getting a TypeScript edition at some stage?
Clinton Gallagher @virtualCableTV on said:
I think I need a course in nested braces and semi-colons with a chapter of SPA debugging tips.
Jone Polvora on said:
John ! I think I’ve made a kind of “Hot Towel” tutorial before knowing about this excellent VSIX template. Take a look at my video in http://www.youtube.com/watch?feature=player_embedded&v=in1M0vzg4mg . Essentially I created a new solution, and installed Breeze, Durandal and Toastr NuGet packages. But your template is better to start fresh ! Awesome work. Thanks for sharing.
Leroy on said:
John,
I love the template and I get a better look-and-feel of the spa and Durandal with Breeze
I do have a question, the splashscreen…. I would like to show this a bit longer any idea where I can adjust this?
Hope to hear from you! Keep up the good work
Leroy
John on said:
Leroy – it will take longer on a real web server, not your dev box . but you can always use settimeout
Leroy on said:
John,
I’m trying to find the right place for the settimeout but it seems like it’s not being recognized or something? Where should I place it?
Leroy
Matt Johnson on said:
@Leroy – I was able to delay the splash screen by putting a timeout in main.js, wrapping the entire app.start() function block. Not sure if this is the *best* place or not, but it works well.
You can use setTimeOut if you want. Or what’s even easier, since Q.js is already there for promises, you can write:
Q.delay(500).then(function() {
// wrap around the existing app.start block
});
Leroy on said:
Yes, that worked for me 2
thanks!
Paul on said:
John,
This is great. The Durandal piece is what I have been waiting for to complete the spa framework. If I wanted to retain the flexibility of deploying to a native mobile device (using Cordova), is there any downside to replacing index.cshtml with index.html including the bundles manually? Obviously all WebApi related projects would remain server side but I don’t see anything else on the client side which isn’t pure html5.
John on said:
Paul , sure. Its perfectly fine to just use the client code. Or look for hottowelette, pure asp.net with no mvc
Matt Johnson on said:
I think I’m in love with this.
Hot Towel? You should have called it Happy Ending!
Seriously though – is there a TypeScript version in the works?
John on said:
Matt – no typescript version of hottowel. yet. depend on interest
Leroy on said:
+1 on TypeScript, I’m kinda eager to see this to!
Leroy on said:
I have searched on Google and came accross Durandal and TypeScript
I needed to change the default controller to point to Durandal (in the views) instead of Home and if it not works restore the packages then it should work fine
Here my adjusted version: http://dl.dropbox.com/u/5117989/DurandalTypescriptExample-master.rar
Here the original: https://github.com/evanlarsen/DurandalTypescriptExample
Gr. Leroy
Ken on said:
Hi John. This is great! Thanks for sharing. I did notice it hangs on the splash view in IE 10. Works fine in FF. Just wanted to give you a heads up.
Leroy on said:
It doesn’t hang here in IE 10! Might wanna check the console?
Uros on said:
+1 on TypeScript version from me too
Ken on said:
Console is clear. All CSS and JS loads successfully (returns 200). Still investigating…
Leroy on said:
I’m using IE10 on windows 8 with 64-bits.
My console isn’t saying alot eiher, maybe delete cache or use another browser. Because if I use Google Chrome for a while it won’t update, if I then use a different browser it shows the new website while in Google Chrome still shows the old one. I bet on cache or something.
Please let us know
Ken on said:
Leroy – I’m also using IE10 on windows 8 with 64-bits. Clearing the cache does not fix it. FireFox works fine so it appears to be specific to IE10 on my machine since it works properly for you. I believe it may be a security setting in IE I need to adjust. Will investigate more over the weekend.
Petr on said:
Why is prefered http://www.breezejs.com/ over http://jaydata.org/ for accessing data?
John on said:
Petr – It’s a preference of style and features. Breeze does everything I need.
Leroy on said:
Dear,
I made a couple of files in TypeScript and rewrote some things. But I wasn’t able to port the shell.js to shel.ts (shell2.ts is a start!)
http://dl.dropbox.com/u/5117989/Hot%20Towel%20TypeScript.rar
Gr. LEroy
Tony on said:
John,
For some reason the template type is not showing up of VS 2012 Ultimate even though I have installed the .vsix ok. Then when I try the nuget package I get the same behaviour as jomarito- I get a 404 of the vendors file. This looks like a tremendous tempate but I can’t get it to work! Any ideas?
-Tony
John on said:
Tony – can you zip up the solution and make it available to me on dropbox so I can try it?
Tony on said:
When I went to went to reproduce the problem things started working. What I did differently was saving the solution before installing the nuget package and also installing the package from the package manager console. In any event, things are working properly. Thanks again for the help.
Matt Johnson on said:
Any chance of a video featuring Hot Towel? I just watched the one on Durandal on their site, and I think much of it will apply here as well. But I’d love to see an end-to-end demo specifically of Hot Towel. Or perhaps highlighting it in one of your excellent PluralSight courses. Many Thanks!
John on said:
I’ll be putting a short HotTowel video together for the asp.net site very soon (travelling this week). And I’ll have a more comprehensive set of videos in my next pluralsight course, SPA JumpStart.
Hoang on said:
John, do you have a expected date for the next SPA course on pluralsight? Thanks.
John on said:
Hoang – March 10th is my due date to get it all in. So shortly after that.
amir hosein on said:
+1 for typescript version
Mladen Mihajlovic on said:
Found this for the people interested in TypeScript: https://github.com/borisyankov/DefinitelyTyped
Russ Hardie on said:
Can anyone provide some resources on how to make a ‘muilt-page’ spa application? For example, a spa ‘page’ to manage customer’s profiles combined with a spa ‘page’ to manage orders, etc….
Thanks
Dhana on said:
Hi John,
With this SPA template i am not able to use the koExternalTemplates discussed in your pluralsight courses. Looks like infuser does its job but ko is not updating the rendering. Not sure if the problem is due to the fact that durandal works on one element (applicationHost) compared to your other SPA course uses body element directly? Any help would be appreciated.
Steps to reproduce:
Start a new project with HotTowel SPA template (search for this template in google if you dont already have)
Via NuGet add koExternalTemplate, which will install traffic cop and infiser as well.
Update BundleConfig.cs to add TrafficCop,infuser and koExternalTemplate
create a folder names Templates under root of the project add a template file. update main js with infuser configs to point to the Templates and file pattern (if you know bit of koExternalTemplate you know what i am talking about).
Include the template in home/details html and launch the app.
Result: you will only see ‘Loading…’ in place of your template and template doesnt get rendered.
same question here: http://stackoverflow.com/questions/15072983/i-upgraded-to-knockoutjs-2-2-1-and-jquery-1-9-koextenaltemplates-are-broken
John on said:
Dhana – Can you share your project so I can test it?
Another option is you could skip the koExternalTemplate and use Durandal for this using its compose binding. It pulls in html using require.js on demand.
Dhana on said:
John, the project is here http://sdrv.ms/XUqyRs Thanks. Meanwhile i will explore compose binding (which mean more rework
)
John on said:
Dhana – The best option is to use Durandal’s `compose` binding with that view. Like this:
<div data-bind="compose: { view: 'templates/_sample.tmpl.html', activate: true }"> </div>And move the templates foler under the views folder (convention).
Dhana on said:
That helps.. Thanks John…
Emmanuel on said:
Hello John,
Template incredible,
I’m new to SPA, and I think this is the best option for this.
I have some questions about the template:
I need to create an application that has a section of widgets, and this section has to work independently of the application, and the footer should have its own functionality while working, so the user can navigate through the modules, and modules must have a communication between them.
How does widget.js works?
Can you give an example?
can I activate more than one view model, so they can work at the same time?
Best regards,
Vindberg on said:
First of thanks for this template. Its golden.
Having created a new empty MVC 4 project, and added the template using nuget its working perfect in debug=true.
Changing debug=”false” in web.config breaks the website. It stalls (404) at /app/main-built.js. Any ideas?
Vindberg.
John on said:
Vindberg – There is a comment in the index.cshtml above the main-built.js call to remind you to run the optimizer if you want to create the main-built.js. That file will then contain a bundle of all of your html and javascript for your app, and saves you from having to make multiple network calls. I don;t create it for you because it would be out of date the minute you add anything to the App folder.
Remember to run the Durandal optimizer.exe to create the main-built.jsBrett on said:
Hi John, great stuff! A bit new to this SPA concept and associated libraries. I am trying to take the binding example a bit further as per your post to Pheenix above. I put some data bound text boxes on the details.html page and have the vm updating the values when the page loads. Since I am making the text box observable in the details.js page, should the ko library fire something to let me know the viewmodel has updated? Here is my code;
var vm = {
activate: activate,
title: ‘Details Plus’,
firstName: ko.observable(‘Chicken’)
};
Nothing seems to fire off (like an update event) that I can see in Fiddler.
Apologies if this is a n00b question! I have tried to do some of the ko tutorials but they dont seem to work in the context of say details.html (presumably due to the viewmodels .js files).
Any direction would be great!
Brett on said:
Sorry to clarify the above a bit more – I am expecting Fiddler to show me when I change the contents of a textbox that has a ko.observable against it. Nothing happens when I change the text box. Do I need to do anything else to update the viewmodel on change of a text box (like call a js function)?
John on said:
Brett – Knockout’s observables will notify between the source (object model) and the data bound targets (HTML). There is no Fiddler activity as it all happens in the browser. When you change a value in your HTML, it updates the observable. When you change the observable, it is reflected in the HTML. The default behavior for text boxes is that it will update the observable when the textbox loses focus.
Asif on said:
Hello John,
Hot Towel Template awesome,
I’m new to SPA, and I think this is the best option for me.
I want to use some Asp.Net Native controls + the some thirdparty controls on the home.html and details.html Views. how i can use them
Thanks
Mathew on said:
Hey John,
Really digging all of the SPA stuff that your doing, great work. I followed you pluralsight course, now I’m trying to get into this hot towel template and I have one quick question regaurding the “dataservice” aspect. For the Hot Towel, would you recommend creating one dataservice that lives in the dataservice folder, separate dataservices for each entity/viewmodel, or simply just using breeze in the viewmodel. I’m new to the whole breeze thing, trying to get a grip on how to best implement it. Thanks for bestowing all of your js wisdom on us, you are a master.
Thanks,
Matt
John on said:
Matthew – I’d start by creating 1 dataservice.js that encapsulates beeeze and the data management logic. You want your viewmodels to look in one place for the data access so they can not duplicate code. Also helps so you can share the data. I’ll have more details in my course in March too. I hope this helps for now!
Mathew on said:
New course! Nice, I’ll be looking out for it. In this new course, do you implement a UoW/Repo pattern with the breeze EFContextProvider wrapper? If so, how do you package that breeze.webapi dll up and place it into your class library? Adding breeze into the mix looks like it will be an amazing help to SPAs
John on said:
Matthew – I don’t spend much time on the server in the beginner course, since I covered a lot of that in the intermediate course that I published last year. You can find a lot of UoW/Repo material there. You could tell Breeze to talk to a UoW and Repo, though you’d still want to surface the EF context to Breeze if you want all the extra goodies that Breeze provides. If you want more details on that, I encourage your to open a question on StackOverflow for Breeze. They are very active up there.
Ward Bell on said:
Matthew – Excellent question … and as John suggests, it would be great if you could ask it on StackOverflow (tag with “breeze”) so other people can get in on it.
In brief, while my controller might create and call a
ContextProvider(typically theEFContextProvider) in demos, in my real apps I always write a server-side UoW/Repository. The Breeze Spa Template starts down this road. It has a Repository class that inherits fromEFContextProvider. In real life, I wouldn’t use inheritance and I’d have multiple projects. But it’s a place to begin. See my discussion here of that example here.Mathew on said:
Sure thing and thanks again to both Ward and yourself. I posted my question to here to anyone else who comes across this and is curious to learn more – http://stackoverflow.com/q/15113804/1968049
Al on said:
Hi John,
Thanks again for another great learning resource. I noticed that Hot Towel does not “define” any of the libraries (ko, jquery, toastr, sammy, etc.) like your Code Camper application does in “define3rdPartyModules” in main.js. Hot Towel just grabs them out of the global scope. Why is this the case? Why did Code Camper do it like that?
I appreciate all of your help,
Al
John on said:
Al – There are a few schools of thought on this. One way is to use AMD and require.js to load all modules on demand (some shimmed). That is what I did in Code Camper. This is more effort as some must be shimmed and some use AMD. Also, some use AMD but leave the object in the glboal space. Others remove it.
Another way is to just use AMD loading for your modules. I have been leaning towards this lately as most of the time I want all 3rd party libraries loaded up front anyway. I bundle and minify them and load in advance. Then load I my modules as needed using AMD/require.js since the dependency chain is more complicated for those (and I may not need some of them).
It is really just a choice and both options work well depending on which pros and cons work for you.
I hope this helps.
Al on said:
Thanks a lot John for your help. I was getting confused with the library bundles and what seemed like redundant defines while everything was pre-loaded and available globally. It is crystal clear now.
Al
Brett on said:
Hi John,
Thanks for the replies above! One more question at this point;
On details.html I have created a few form fields (as noted above) and want to fire off an event from a button click (like update the view model, which should reflect in the fields). Code below. When I click the button I get an error UpdateVM() is undefined. Is the script getting lost/conflicting in the structure somewhere?;
function UpdateVM() {
this.firstName.value = “Bertie”;
}
First Name:
Last Name:
Brett on said:
Sorry HTML tags were cut out. imagine a two fields as textboxes with a data-bind of value: firstName and value: lastName. Data is getting into those fields from details.js, so I know the binding is working.
John on said:
Brett – To use data binding you should use Knockout’s binding syntax. Like this
<input data-bind="value: firstName"/>The view model would have an observable like this
this.firstName - ko.observable('Bertie');And you bind the viewmodel to the view using
ko.applyBindings(new MyViewModel())I recommend checking out Knockout’s syntax first on their web site or I have a course at Pluralsight on Knockout at http://jpapa.me/komvvm
If I am misunderstanding, please clarify. I hope this helps!
Brett on said:
Hi John,
Yeah I understand a bit about ko at this point. What I am getting confused about is where I put the viewmodel update javascript code. I have added a button to the form on details.html that has data-bind=”click: updateMe()” on it. Where should the function updateMe() live (details.html, details.js? if latter, where in details.js?) If you could please provide me with an example it will save a lot of head-on-desk contact
. I have tried both locations, but nothing fires. I feel like it should work in either, but not sure about where to place the script …
Cheers,
Brett
Bob on said:
Thanks for this article, quick, simple and well written!
SPA makes tedious tasks so much easier.
Jitendra Singh on said:
Are you planning to publish a tutorial on pluralsight ?
John on said:
Jitendra – Yes, I will be publishing a beginner course on SPA that is based on HotTowel in March via Pluralsight.
Asif on said:
Hello John,
I’m new to SPA, and I think this is the best option for me.
I want to use some Asp.Net Native controls + the some thirdparty controls on the home.html and details.html Views. how i can use them
Thanks
Dung on said:
http://stackoverflow.com/questions/15131297/how-can-i-use-durandal-mvc-controller-in-viewpath
Hi John ! I want to use Durandal with Mvc using controller, razor. How can i do it. Thanks. Could you please make some example, the view will be controller/action ?
Thanks !
Dave on said:
Dear Mr Papa.
I am using yout hottowel template as the base framework for my app. I would like to use kendo ui treeview control . But its based on mvc and not on mvvm. Can you. Please advise on how to handle this. Is there a way to combine mvc with mvvm or…?
Greatly appreciate your work and love your pluralsight vids
David Stanescu on said:
+1 on TypeScript version
Leroy on said:
John,
I’m trying to use this template with TypeScript and so far everything is kinda working out just right, but I won’t succeed implementing BreezeJS in TypeScript in this template. When I’m developing there is no problem but when I try to run the page with the BreezeJS implemented it says JavaScript runtime error: ‘Breeze’ is undefined. Do you have an example or a simple solution on how to deal with this? I checked and breeze.min.js and breeze.debug.js or but loaded in. Could this be something with capitals or….
Hope to hear from you keep up the good work
Leroy
Ward Bell on said:
Not sure what you’re doing but it can’t be a good thing if the message refers to “Breeze” because (a) case matters and (b) it’s lower case “breeze”
Leroy on said:
This is my typescript file
[code]
///
///
///
import app = module('durandal/app');
import logger = module('services/logger');
export module Services {
export class Dataservice {
//serviceName = "api/customer";
//serviceName: string;
Manager: Breeze.EntityManager;
EntityQuery: Breeze.EntityQuery;
constructor(/*serviceName: string*/) {
this.Manager = new Breeze.EntityManager("api/customer");
this.EntityQuery = new Breeze.EntityQuery("Customers");
}
getAllCustomers() {
//var query = this.EntityQuery
//.from("Customers");
var query = new Breeze.EntityQuery("Customers");
//logger.log("fdfds",null,"dasd",true);
return this.Manager.executeQuery(query);
}
}
}
[/code]
Ward Bell on said:
In Durandal world, 3rd party libraries are loaded first and outside of Require.js purview. Their scripts load objects directly into the global namespace (‘window” on a browser) with names of their choosing. Typically they load objects and regular function which, by JS convention, are camelCase. So it is ‘breeze‘, not ‘Breeze’, ‘jquery‘, not ‘Jquery’, etc. TypeScript is JavaScript and does not change that.
John on said:
Hi John, thank you for the great work.
I do have a question about routing which I’m sure is not specific to HotTowel but maybe to Durandal or Sammy.
Let’s say that I just want to put a link on the foot to /securityguard/dashboard. I’m using security guard for user management. If I just do this Administration It never takes me there. Instead I get an error about the module returning HTML instead of JS. If add a target=’_blank’, then it works fine, but that’s not what I want.
It would also be great if I could add the same link to the navigation on top.
Any suggestions?
Thanks
Rob Eisenberg on said:
That’s a bug in the Durandal router which has been fixed and will go out in the next release. If you want to use the improved version now, you can grab it from the repo.
John on said:
Rob, will I just need the router.js? or do I need everything from it for this fix?
Thanks
John on said:
Thanks Rob.
I will get the repo and go from there.
João Vitor PBC on said:
+1 on TypeScript version of this.
Oscar Agreda on said:
Well played, John, you are always way ahead of the curve, as in the past, software development always follow your discoveries
Have you considered adding one more punch to you awesome HotTowel Template
http://addyosmani.github.com/jquery-ui-bootstrap/components.html
Regards
Matt on said:
Given the whole “One ASP.NET” concept http://www.hanselman.com/blog/ASPNETAndWebTools20122ReleaseCandidate.aspx,
is there any chance we will see a SPA application built using Web Forms?
John on said:
Matt – My intermediate SPA course at Pluralsight uses a standard HTML page and if you use the HotTowelette NuGet package, you get a SPA with regular ASP.NET.
Matt on said:
I guess what is so hard to get up to speed on in the intermediate course is
how many abstractions the app has related to the data layers.
The course seems way more about those issues and design patterns
then about javascript. The problem, at least for me, is that it also assumes a lot of prior experience on how to implement those patterns in .net.
I like working in SQL, have no taste for EF Code First, and rely heavily on stored procs, especially for complex cases where I pass multiple parameters and then return multiple recordsets using WebMethod() calls
in code behind and jquery/knockout on the client. So this is “bad”
because of lack of separation of concerns. I am searching for instruction
or examples of how to include a measure of abstraction, but I guess I
have to yet to come across a tutorial or “how to” that just clicks for me:
“ah, this is how I would re-write the existing code with a better separation
of concerns”. My sense is part of this should be really simple, but I lack
the confidence without first seeing a real example.
Mathew on said:
Hey Matt,
Yea I had the same problem, except I’m just coming into the stuff (still a student). It sounds like you have a pluralsight account already, so I’d recommend you check out Julie Lerman’s Entity Framework in the Enterprise (Great Course) and maybe her new Getting Started with Entity Framework 5 as well if your new to EF like I was. Entity Framework in the Enterprise, I thought, really helped me get a grasp on how SoC can be effectively implemented using EF. If it doesn’t help, well then you still took an interesting course. Hope that helps
Greg Donovan on said:
Hi John – we are sold on your Hot Towel design
Our app will requie some rich client-side grids – what grids, if any, do you recommend (Wijmo, Telerik, jqxwidgets…to name a few)?
Regards,
Greg
John on said:
Greg – There are several good ones. But I first try to design my sites without a grid and use a template for rows. I only use a grid if I need something I can;t do easily without one. Grids come with a price (overhead and complexity). But if you want a grid, any of the major vendors has a decent grid, just make sure it has a binding handler for Knockout (if you are using KO). Or you can use a more common one like datatables.js
Alex Maiereanu on said:
Hi,
Thist of all i want to thank you for all the support you give us for staying in touch with new technologies
.
Have you given any thought on how do make spa’s searchable by google? I want to apply the spa principle to a web shop project where some of the data should be crawlable by google. I read the google guidline (https://developers.google.com/webmasters/ajax-crawling/docs/html-snapshot ) on how to do this for ajax content. but i can’t figure out how to create a reusable way to make html snapshots. I am thinking to provide custom routes for content that i want to be indexed,showing exactly what i would have otherwise loaded thru ajax.
Alex
Rad on said:
Alex,
Do you have some some samples available that try to use searchable SPA design?
John,
This would be a very nice addition to SPA.
Thanks,
Rad
Alex Maiereanu on said:
Hi,
I will play around with this feature in the near future for a project i am working on. If it works out alright i will post some example code
Alex
Tiago Reis on said:
-1 for Typescript in Hot Towel. Although TypeScript can certainly be a good thing, etc, I think developers should really start paying more attention to JavaScript, and to be able to write proper JavaScript. Why abstract (maybe due to lack of knowledge in proper JavaScript?) when one can structure JavaScript in a very powerful way? It’s just my opinion of course.
Mike on said:
@Tiago, TypeScript is a superset of JavaScript. This means you still have to know JavaScript. Here is what I like about TypeScript every time I write code in JavaScript it starts with me doing a search for “JavaScript Module Pattern” so I can remember what the code is for the module pattern.
So instead of:
var MODULE = (function (my) {
my.anotherMethod = function () {
// added method…
};
return my;
}(MODULE));
you can just write:
module Module {
function anotherMethod() {
// added method…
};
}
Also the type checking is a huge win. In the above example, if I was passing a variable to anotherMethod like this anotherMethod(url), if I try to pass a number as url, the IDE will light up immediately and tell me that url requires a string. You still have to know JavaScript, as all of the code you put inside anotherMethod is still JavaScript, it just makes your code more readable and saves you from shooting yourself in the foot. This foot saving is much more apparent when dealing with a large code base, but still helpful when dealing with a small code base. In my view it is a productivity tool, it helps me write code faster, the code is more readable, and the type checking lets me catch where I passed the wrong variable or typo’d a variable name write after I type it instead of waiting until I run the code and have to debug why something isn’t working. I think your comment would apply more to something like CoffeeScript where the syntax is completely different. For TypeScript, you still have to write JavaScript and you still have to understand it.
Nik Ivancic on said:
This little jewel on how to use TypeScript in the context of what you do is greatly appreciated.
Tiago Reis on said:
@Mike, I totally get what you are saying. Maybe I’m just a purist when it comes to JavaScript
but if I was, I wouldn’t like Durandal so much (because I’d try to do everything by myself). Time will say if I’m going to start using it
Randhir on said:
John:
Please suggest me which is best way like (breeze or durandal) using the hot towel template.
John on said:
Randhir – Both. Breeze is for rich data and Durandal is the app lifecycle and view composition Both together are a good combination.
LastTribunal on said:
John,
I’m trying to figure out how to implement a jquery method inside a hottowel viewmodel.
Can you provide an example?
Thanks and my apologies for the stupid question
var vm = {
activate: activate,
title: ‘Applications’
};
return vm;
LastTribunal on said:
More specifically, i am trying to implement Dyntree (https://code.google.com/p/dynatree/) inside the viewmodel:
$(function(){
$(“#tree”).dynatree({ onActivate: function(node) {
alert(“You activated ” + node.data.title);
}, children: [{ title: "Item 1" },
{
title: "Folder 2", isFolder: true, key: "folder2", children: [{ title: "Sub-item 2.1" },
{ title: "Sub-item 2.2" }]
}, { title: “Item 3″ }]
});
});
Emmanuel Tolentino on said:
thanks John,
Excellent course, I just seen your “Single Page Apps JumpStart” course at pluralsight, and is excellent.
I have solved some doubts that I had.
Sathyan on said:
We have an application with a backend in .net and SQL Server database with front end in Power Builder. The plan is to give it a thin client I.e browser based UI. The application has over 1000 screens divided into 25 modules.
What would be the best way to create a SPA for it.
Please advice
Joseph on said:
Hi John,
Great training, I loved it. I could say enough about your training is going to help me in my upcoming project.
What we are trying to re-write is huge application. It will require more than one SPA inside web site. How would you advice me to do that. Can we have multiple sub folders under App folder representing each spa? Can you advice me how I go about and achieve this goal?
Thanks
Joseph
John on said:
Joseph – Thanks, I am happy you enjoy the material.
First consider if you need more than 1 SPA. If there are a lot of views, that’s fine. But if you mean to have different apps or areas of apps that act very differently, and all should be hosted in the same MVC app, then that’;s fine too. The key is that the theme and the client state between these apps should be the same. Theme can be done via CSS and state via postback or local storage, to name a few. This will be a topic I hit in a future course.
Joseph on said:
Hi John,
Thank you for your quick response. I really do appreciate it.
Our Main web site will have navigation bar on the left side and each item in there will be different application. The MVC app is going to be the same. But client state is going to different most of the time, the themes will the same.
Thanks again John. Looking forward to your next series.
Joseph
Richard Davison on said:
John, Love your stuff.
Trying to make it my own and add authentication.
I have started with the Durandal sample and added things denoted here
http://stackoverflow.com/questions/15462746/durandal-mvc-app-authentication-security
as noted there I have a sample that is 98% working (everything is wired up and appears to be correct, but when I hit the logout button the content in the browser does not change even though success messages are received).
Also please note that clicking logout twice seems to cause a javascript error.
Thoughts?
RD
John on said:
Richard – Provide the sample via SkyDrive or Dropbox please so I might take a look at it.
Richard Davison on said:
https://www.dropbox.com/sh/sfubdmdct8wpz2a/BLkN6epx0V?m
as promised.
all you should have to do is connect to a db with the simple membership tables and a known user id and go from there.
Have not had a chance to impliment register yet…
Included scripts for simple membership tables as well.
please see global.asax
RD
simon dowdeswell on said:
John Im new to JS/jQuery. it took me a long time to work out that these breeze js calls are defined by manager = new entityModel.EntityManager(‘api/Customer’); are not portable to any deployment. If i deploy to a virtual directory, say cs2 then my code needs to be:
manager = new entityModel.EntityManager(‘cs2/api/Customer’);
in order to work.
Is there a better way to work out the real path
John on said:
Simon
These are your Web API calls, and are common in any ajax application. Some common techniques are to create a root string variable such as
var rootUrl = 'cs2/api';. Then when you move elsewhere it is an easy change. Generally I have a config.js file for this stuff.Ward Bell on said:
@simon – I think when you look a bit closer at BreezeJS you’ll find that the standard thing to do is define a base path (e.g.
var serviceName = 'cs2/api/myAppController') which routes to a single controller. Put that in configuration. Change it at will. In yourrepository/UoW/datacontext/whatever-you-call-it, reference that configuration when creating an EntityManager, e.g.:var manager = new breeze.EntityManager(config.serviceName);Then you specify resource names in EntityQuery construction:
var custQuery = new breeze.EntityQuery.from('Customers'); var prodQuery = new breeze.EntityQuery.from('Products');You say “but Ward, I don’t want all of my resources in a single controller”. Not a problem. Redefine your service name in config to something like
'cs2/api/'and then define your query resource name with the controller:var custQuery = new breeze.EntityQuery .from('customers/Customers'); var prodQuery = new breeze.EntityQuery .from('products/Products');That seems kind of silly to me so I could do some server-side routing to get back to:
var custQuery = new breeze.EntityQuery.from('customers'); var prodQuery = new breeze.EntityQuery.from('products');The routes would channel these requests to appropriate controllers and actions. Not a big deal. Aside: you’ll have to do some server-side custom routing of the EntityManager requests to the appropriate “Metadata” and “SaveChanges” endpoints but that’s pretty trivial. If I’m using a Breeze controller on my server that can handle queryables, I’m not loving this controller-per-type approach because I’m going to end up with a lot of controllers that only have one method. But maybe you don’t want that kind of controller and instead want lots of very specifically named actions. You can do that too:
var custQuery = new breeze.EntityQuery .from('customers'); var custQuery = new breeze.EntityQuery .from('customers/getGoldCustomers'); var custQuery = new breeze.EntityQuery .from('customers/'+42); // get customer with id=42 var custQuery = new breeze.EntityQuery .from('customers/startsWith') .withParameters({name: 'b'});It’s not hard. It just means having server-side endpoints that understand the resolved URLs. More detail is beyond the scope of this comment. My point is … you’re not handcuffed … like you might have thought.
simon dowdeswell on said:
Thanks, Ward, John for taking the time to help me out !
for my config ive gone with working out the base url :
function processBaseUrl() { var baseUrl = window.location.pathname; var urlLength = baseUrl.length; if (urlLength > 0) { if (baseUrl.charAt(urlLength - 1) !== '/') { return baseUrl + '/'; } } return baseUrl; }These points you raise, Ward are exactly whats on my mind … only 1 controller … too many controllers … I am in favour of more specific requests so that the name can indicate the intention.
I will be looking into the routing as you indicated.
one small point – i tried to switch the project over to basic jQuery AJAX and couldnt get it working (gave me 404 even though the path was good) until I commented out the whole HotTowelRouteConfig and put the route in with the standard RouteConfig.RegisterRoutes ie:
routes.MapRoute( name: "HotTowelMvc", url: "{controller}/{action}/{id}", defaults: new { controller = "HotTowel", action = "Index", id = UrlParameter.Optional } );I would have thought the two were equivalent … but obviously not
Rody on said:
I’ve added a new view and viewmodel to a new project. Added an extra router.mapNav() to this view, but the view is not loaded:
router.mapNav(‘details’);
router.mapNav(‘subdetails’);
Whenever I click on the menubar on subdetails the details view gets activated. I think it has something to do with durandal using the url paramter of router.mapNav as regular expression, but I don’t know how I can force the router to use the entire string instead of a regular expression.
John on said:
Rody
There appears to be a bug in either Sammy or Durandal. I created an issue in Durandal’s github repo for it. In the meantime, you can solve this 2 ways: either put the subdetails first (so its foudn first) or change the name of subdetails.
https://github.com/BlueSpire/Durandal/issues/104
Ronnel on said:
Hi John,
how would u do a data driven menu/routes?
John on said:
Ronnel – Pull the menus from a database via an ajax call, then load into the router instead of hard coding.
Leroy on said:
For those who want to use FancyBox inline
http://stackoverflow.com/questions/15503981/single-page-application-and-inline-fancybox-not-working-properly
For further
http://stackoverflow.com/questions/15436844/how-to-use-fancybox-in-combination-with-durandal-en-typescript
Trust me this took me a full day to figure out
Mike on said:
John,
I installed the vsix file and I’m running VS 2012 Premium but I don’t see the templates when installed when I select ASP.NET MVC 4 Application. Anything else I can try?
Mike on said:
Forget my last comment. I got it working with the Nuget package. Sorry.
Paul Wade on said:
Hi John,
Can I get this working with VS2010?
Regards,
Paul.
John on said:
Paul – Yes, but not the VSIX (that requires VS 2012). You can use the NuGet packages nuget.org/packages/hottowelette or nuget.org/packages/hottowel
Paul Wade on said:
Hi John,
Just to let you know…..
I downloaded the completed exercise files from your PluralSight course and successfully converted it to run with VS2010.
I followed Adam Storr’s article on how to do the conversion, so a big thank you to Adam http://westdiscgolf.blogspot.co.uk/2012/09/opening-pluralsight-single-page.html
Also… I need to get my VS2010 HotTowel running with IE8, can this be achieved using Shim and Sham files? Do I have to include them in the BundleConfig?
Any help appreciated.
Regards,
Paul.
JcFx on said:
+1 for a TypeScript version.
Raymond Suelzer on said:
What is the purpose of widget.js ? It is not included in any documentation that I have seen.
Raymond Suelzer on said:
Found my own answer: http://durandaljs.com/documentation/Creating-A-Widget/
Anthony Chu on said:
Here’s what it looks like with TypeScript. I converted the viewmodels and a couple other core JavaScript files to TypeScript.
https://github.com/anthonychu/HotTowelTS
One immediate advantage is the fully functional intellisense you gain with TypeScript. That’s huge as Visual Studio’s built-in JavaScript intellisense doesn’t work at all with RequireJS and AMD.
John: Thanks for the awesome courses on Knockout, TypeScript, and SPA. It’s been a joy to learn about and work with these tools!
Daniel on said:
Hi, is this extension also available for VS 2010?
John on said:
Daniel – the NuGet packages work in VS 2010
Agustin Cassani on said:
Hi John, thanks for this incredible template! I have used it in many projects with ASP.NET 4.5 with no problems at all but I am facing some troubles trying to apply it to older projects done with ASP.NET 4.0 The error message says something related to EF and its dependencies but I am pretty sure that that is a general error and the real one is somewhere else. Could you tell me what do I need to set up in order to use this template with ASP.NET 4.0 or is it impossible? Thanks in advance!
ccliu on said:
Hosting Question: SPA is normally File URI Scheme or hosting on server such as IIS?
Great video, thanks!
Sverre on said:
Hi John, thanks for the excellent SPA template. I am trying to use it in a real world project with several layers. There is a data layer based on EF in a separate project but I am hesitant to introduce a dependency on Breeze EFContextProvider in this layer. On PluralSight you have a similar scenario in the “Single Page Apps with HTML5, Web API, Knockout and jQuery” course and using dependency injection. How would you recommend using the Breeze EFContextProvider in this situation?
John on said:
Sverre – You can use the UoW and Repo patterns on the server and just have Breeze sit on top of them.
Fred on said:
John, Thanks for this great framework.
one of my clients requires an app to run on iPad and the web, but when running on the iPad we require offline data. I plan to use phonegap, is hottowel the best framework to do it in ?
TIA
Fred
John on said:
Fred – I haven’t taken the exact HotTowel stack to phonegap yet. But the concepts should translate well. Sounds like a great idea for a new course
CB on said:
Hi,
I’m enjoying your SPA pluralsight course… Well, I was, right up to the part after installing the entityframework.sqlservercompact and you say, “Now, we go to our fragments folder and bring in….”
Where the heck is the “code/fragments” folder? You never say in the video!
Thanks for any pointers…
C. Bates
John on said:
CB – Thanks for the feedback. I am glad you are enjoying the course. The example code is available with a Pluralsight Plus subscription.
Andre on said:
I started to follow the videos on `pluralsight` about this template. But I have already a question: Can I use Kendo UI MVVM pattern to do the bindings instead of using knockout? Or need I to use knockout with this kind of template? Sorry if this is a basic question, but I’m starting now in the web development.
Thanks in advance!
John on said:
Andre – I have not tested Kendo’s MVVM pattern with Hot Towel. But it could certainly work.
Rody van Sambeek on said:
John, in your pluralsight video it seems you have intellisense using durandal. But I’m not sure, because it shows really fast. When I use the HotTowel template in my own project, I don’t get the correct intellisense from modules I load in using durandal.
Is this resharper working? Or do you have specific settings to get this working?
John on said:
Rody – Without named modules using AMD, it doesnt work well in VS. I use Resharper and it helps greatly.
Simon on said:
A HowTo question: I have a view that I want to be reusable – selectCustomer. when i call router.navigateTo(‘selectCustomer’)
what is a good way to supply a callback, to be used in selectCustomer, to be called when the customer is selected.
Currently I have an appNavigation service to set a selectCustomer Callback property and then navigate to it, but its kind of global so no stack (the viewModels are all singletons) … a bit cludgy. I would rather call:
router.navigateTo(‘selectCustomer’, new selectCustomerVm(callback))
note i am a js noob, so I dont actually know how to expose the selectCustomerVm class and get a new instance with the require injection mechanism