I am working on replacement ASP.NET MVC+Knockout with just Knockout, I want to remove ASP.NET and get just static js + html.
My ASP.NET views consist of Partial views (I call them widgets in my project), this Partial views easily replaced with Knockout components.. but I have a problem: ASP.NET Partial views have a Layout (some html decoration for every widget), how can I achieve similar for Knockout component view?
Simplified example. Old asp.net scheme:
View.cshtml:
<div>
@Html.Partial("SomeWidget")
</div>
SomeWidget.cshtml:
@{
Layout = "~/Views/Shared/_WidgetLayout.cshtml"; <!-- parent layout for widget -->
}
<span>This is some widget</span>
_WidgetLayout.cshtml:
<div>
<span>This is decorator for every widget</span>
@RenderBody() <!-- render widget view here (SomeWidget.cshtml in this example) -->
</div>
New knockout-only scheme:
View.html:
<div>
<some-widget></some-widget>
</div>
View.js:
ko.components.register('some-widget', { require: 'app/SomeWidget' });
SomeWidget.html:
<span>This is some widget</span>
SomeWidget.js:
var view = require('text!/views/SomeWidget.html');
return { template: view };
How to replace _WidgetLayout.cshtml in Knockout?
There are several ways you could possibly do this. The simplest way I can think of is to have a template component, and you nest the widget inside this. KO Components support nesting.
You can define a template component thus:
ko.components.register("widget-template", {
viewModel: function(params) {
var self=this;
self.WidgetName = params.widget;
},
template: "<div class='b'><span>This is decorator for every widget</i>
<div data-bind='component: { name: WidgetName }'></div></div>"
});
To use this, you put the template-widget into your HTML, and pass the name of the widget as a parameter:
<widget-template params="widget: 'widget1'"></widget-template>
Then you define a widget as another component:
ko.components.register("widget1", {
template: "<h3>Widget One</h3>"});
So now you have a re-usable template that can wrap any component. You can see more about this binding in the Knockout documentation.
See the full JS fiddle here: http://jsfiddle.net/Quango/a8h2bwtc/
Note that you can also make the name an observable rather than a static value, as seen here: http://jsfiddle.net/Quango/tnphvvgd/