Durandal.js just recently came out and so far it appears to be a simply awesome lightweight modular framework for creating single page JavaScript applications using pure Knockout goodness.
I switched over the Survey App demo of FluentKnockoutHelpers to use Durandal.js. Its been fun learning to use: Durandal just feels very clean and ‘right’ so far!
The instantly-runnable via F5 demo highlights the power of combining FluentKnockoutHelpers for strongly typed helpers (MVC-like) that work on the client, with the databinding/code organization of Knockout.js/Durandal.js combo.
Take a look at the updated code and I’d love to hear people’s thoughts about Durandal.js (is it the new best JavaScript framework this week?) and how the FluentKnockoutHelpers are shaping up.
Run the SLN at (/demo/SurveyApp.sln)
FluentKnockoutHelpers using Durandal.js for demo
hey john. nice sample. yours is the first/only that i could find that combines the use of durandal with razor web pages. this is exactly what i was looking for! i was not wanting to lose the power of unobtrusive validation coming from the server/model. so thanks! my only issue is i can't seem to figure out why my project isn't finding the cshtml files. i did add the reference in the main.js to use the .cshtml extension. it seems it's not finding my shell.cshtml file though. the error i'm getting says 'The request filtering module is configured to deny the file extension.' But i'm not expressly denying the cshtml extension anywhere that i know of (web.config).
any ideas?
Hey Eric,
Glad you like the demo! I'm hoping to build out the most comprehensive demo of Durandal.js available online with this (so far it's still pretty new of course…). I think I know what your issue is: By default when using MVC, CSHTML files cannot be served up directly because they are supposed to be served up by a Controller Action. If you are using an MVC project your Web.Config is likely set up this way, to block CSHTML directly (not sure where since you said you can't see it…?). Take a look at this web config which operates on all views in it's folder and below it (most Durandal views in the site) https://github.com/johnculviner/FluentKnockoutHelpers/blob/master/demo/SurveyApp.Web/App/views/Web.config
Notice how it is very simple without any "BlockViewHandler" declared. If you add/update your web.config to be like this one in your /App/Views and see if that helps. Let me know. There is lots more Durandal.js / FluentKnockoutHelpers goodness to come. Next I'll be sending DataAnnotations down to the client…
thanks john, i was thinking it must be something with that web.config as well. i tried using yours exactly as you posted it, and also tried making some modifications to mine, but to no avail. something else is still causing the issue. the project template i started with was the visual studio durandal template from their website. i made no major modifications to either web.config. i am running it in IIS, and not localhost, although that 'shouldn't' make a difference.
//**viewEngine.js**//
define([‘./system’], function (system) {
var parseMarkupCore;
if ($.parseHTML) {
parseMarkupCore = function(html) {
return $.parseHTML(html);
};
} else {
parseMarkupCore = function(html) {
return $(html).get();
};
}
return {
//**********SeeThis***////////
viewExtension: ‘.cshtml’,
//**********End***////////
viewPlugin: ‘text’,
isViewUrl: function (url) {
return url.indexOf(this.viewExtension, url.length – this.viewExtension.length) !== -1;
},
convertViewUrlToViewId: function (url) {
return url.substring(0, url.length – this.viewExtension.length);
},
convertViewIdToRequirePath: function (viewId) {
return this.viewPlugin + ‘!’ + viewId + this.viewExtension;
},
parseMarkup: function (markup) {
var allElements = parseMarkupCore(markup);
if (allElements.length == 1) {
return allElements[0];
}
var withoutCommentsOrEmptyText = [];
for (var i = 0; i < allElements.length; i++) {
var current = allElements[i];
if (current.nodeType != 8) {
if (current.nodeType == 3) {
var result = /\S/.test(current.nodeValue);
if (!result) {
continue;
}
}
withoutCommentsOrEmptyText.push(current);
}
}