Hack: using live bindings outside templates
A comment on this post is asking whether it is possible to create bindings outside of a template. The point of doing that is that you don’t necessarily want to render a template just to set-up a few bindings.
Well, bindings are really implemented by a component, Sys.Binding, and a markup extension, which instantiates that component through the convenient {binding foo} syntax.
While the markup extension is only understood by the template engine, the component can be instantiated like any other component, through $create or declaratively (thanks to Dave for pointing me to how this can be done).
Here is a sample page where two bindings are created (imperatively and declaratively) to bind a span’s text (imperatively) and an input’s value (declaratively) to the same plain JavaScript data object. Modifying the value in the input changes the data object, which in turn changes the span that is also listening to it.
<%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Binding</title> <script type="text/javascript"> var data = { answer: 42 }; function pageLoad() { $create(Sys.Binding, { target: $get('answerDisplay'), targetProperty: 'innerText', source: data, path: 'answer', mode: Sys.BindingMode.oneWay }); } </script> </head> <body xmlns:sys="javascript:Sys" xmlns:binding="javascript:Sys.Binding" sys:activate="*"> <form id="form1" runat="server"> <asp:ScriptManager runat="server" ID="SM1"> <Scripts> <asp:ScriptReference Path="~/Script/MicrosoftAjaxTemplates.js" /> </Scripts> </asp:ScriptManager> <div> <span id="answerDisplay"></span><br /> <input type="text" id="answer" sys:attach="binding" binding:target="{{ $get('answer') }}" binding:targetproperty="value" binding:source="{{ data }}" binding:path="answer" binding:mode="{{ Sys.BindingMode.twoWay }}" /> </div> </form> </body> </html>
Not quite as convenient as being able to directly use the markup extension but it gets the job done. Please also be aware that the overhead in rendering a template is very small and the convenience of the markup extension may be preferred over this. Here is the same page using a DataView:
<%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Binding</title> <script type="text/javascript"> var data = { answer: 42 }; </script> </head> <body xmlns:sys="javascript:Sys" xmlns:dataview="javascript:Sys.UI.DataView" sys:activate="*"> <form id="form1" runat="server"> <asp:ScriptManager runat="server" ID="SM1"> <Scripts> <asp:ScriptReference Path="~/Script/MicrosoftAjaxTemplates.js" /> </Scripts> </asp:ScriptManager> <div sys:attach="dataview" dataview:data="{{ data }}"> <span id="answerDisplay">{binding answer }</span><br /> <input type="text" id="answer" value="{binding answer}"/> </div> </form> </body> </html>