I would like to use some JavaScript controls, which have KnockoutJS binding handlers already implemented. After reviewing the DotVVM tutorials, such as "Code-only Controls" and also the controls from the DotVVM source code, I am confused on what aspects of and to what extent the controls need to be rendered via the DotVVM "Rendering Pipeline," if indeed they need to be.
Also, if the controls already have KnockoutJS binding handlers already implemented, is the process of wrapping them the same as for controls which do not have KnockoutJS binding handlers already implemented?
If you already have Knockout binding handlers, you just need to write a control to render the appropriate HTML.
The only difficulty here is that the values of control properties may be hard-coded in the markup, or it can be a data-binding. Some properties allow only one of these ways, some allow both.
Basically, you need to create a class inherited from
HtmlGenericControl
and tell it which HTML element it should render, in the base constructor. For example:public MyControl() : base("div")
.Then you need to declare control properties. Use the
dotprop
code snippet to generate the property body, and using theMarkupOptions
attribute you can disable hard-coded values or data-bindings if it doesn't make sense.And finally, you need to render the HTML. If you need to render only the
data-bind
attribute, you need to override just theAddAttributesToRender
.You can call
writer.AddKnockoutDataBind("myBindingHandler", this, MyProperty, () => { /* handle the hard-coded value */ } )
. If the property contains a data-binding, it will get translated automatically. If it contains a hard-coded value, the last argument (the lambda) will be called.If the control is more complex and uses templates or invokes postbacks, you need to build child controls inside the control, set their bindings properly and you don't need to render them manually in that case.
There are several reasons why DotVVM uses such a complex rendering pipeline:
if
statements. Sometimes, the binding is evaluated on the server, sometimes it is translated to JS. Moreover, some controls are very complex and need to build some child controls.data-bind
attribute. They are separated by a comma, so the API handles the concatenation and translation to proper JavaScript expressions.AddAttributesToRender
,RenderBeginTag
,RenderContents
andRenderEndTag
methods allows to extend the controls using inheritance. We have copied this from ASP.NET Web Forms because it worked quite well.If you can provide an example of what are you trying to render, I can give more specific answer.