Atlas introduces a new declarative script format for defining script object instances, their property values, and how they wire up to each other. This has sparked some discussion at PDC05 as well as some discussion on our internal discussion lists as well. Sounds like this is worthy of a blog post, and sharing thoughts and opinions.
For example, one might define a basic search UI as follows:
<input type="text" id="searchText" />
<input type="button" id="searchButton" />
<script type="text/xml-script">
<page xmlns="http://schemas.microsoft.com/xml-script/2005">
<references>
<add src="ScriptLibrary/Atlas/AtlasUI.js" />
<add src="ScriptLibrary/Atlas/AtlasControls.js" />
</references>
<components>
<textbox id="searchText" />
<button id="searchButton">
<bindings>
<binding property="enabled"
dataContext="searchText" dataPath="text.length"
transform="NumberToBoolean" />
</bindings>
<click>
<!-- Call the invoke method of ServiceMethod when the button is clicked -->
<invokeMethod target="searchMethod" method="invoke" />
</click>
</button>
<serviceMethod id="searchMethod">
<bindings>
<!-- Bind the query field of the parameters property of the
ServiceMethod to the text property of searchText
(and keep them in sync) -->
<binding property="parameters" propertyKey="query"
dataContext="searchText" dataPath="text" />
</bindings>
</serviceMethod>
</components>
</page>
</script>
One of the ideas behind this script markup is to allow you to define the behavior of your application and its user interface as a separate layer that is attached to the content and style layers. Sure this can be done in imperative code, but declarative markup has some nice characteristics.
- First and foremost declarative markup is more designable that code. This approach will facilitate tool development in the future.
- Second, it is actually simpler for atlas-enabled server controls to emit or render their script-based functionality in the form of markup (similar to HTML markup) using constructs such as XmlTextWriter.
- Third, declarative markup enables you to specify what the app needs to do, and not necessarily how. Frameworks can capitalize on the ability to interpret semantics and do interesting things - for example imagine running script functionality on the server to generate an initial view of the page, or a view of the page more suitable for search engines.
- Lastly, it may be simpler to represent simple scenarios where JavaScript code would require script coding, several event handlers to keep all components in sync (in the example, see how the enabled state of the button is keyed off text entry, and is automatically synchronized without having to write a change handler), which is error prone and hard given the lack of mature tools.
I have blogged about declarative programming in a different context in the past. What I believe in is that the code-intensive aspects of the application should be packaged into components that can then be glued together primarily using declarative markup, and perhaps with minimal imperative code. Atlas goes some ways in enabling this, with things like bindings and actions. There are still some key concepts that need to be added to the toolbox to meet the needs for mainline scenarios.
While we have introduced xml script, everything we are doing in atlas is designed to be usable from imperative code as well. In fact, if performance of xml parsing is suboptimal in a particular browser, the server could dynamically convert the xml into the equivalent script on the fly. Components are authored using code, and use atlas building blocks in an imperative fashion. Secondly declarative markup is complementary to script. Both may be used on the same page.
One other thing I should mention (or it is bound to result in some confusion) - I would not expect everyone to have to go out and learn yet another xml format. That is simply not the intent. Server controls can completely provide an abstraction where the familiar server-side programming model is used for development, but server controls under the covers, generate this markup alongside their normal and existing markup rendering.
How we came up with this somewhat unconventional or perhaps strange approach?
The goal was put our xml markup inline in the document in such a way that it would be ignored by the HTML parser. This meant we couldn't do something like invent a custom tag, or put into an <xmp> tag or something similar. One thought was to put it in a comment, but that doesn't help find it in code, and secondly, the xml isn't really a comment to begin with. We wanted it to be inline, rather than serving it up via an alternate URL so we wouldn't have to make an async call to the server to retrieve this content, because the page is in an intermediate stage while this script is loaded and processed. Our thoughts turned toward using a comment in regular script. That led to the question of whether script really needed to be JavaScript at all. Experimenting with xml as the format of the script revealed the browser is totally fine with it. Furthermore, the script tag perfectly captures the true semantics. Script component definitions are after all script functionality, but expressed in a markup form. Hence <script type="text/xml-script">. I actually really love the concept...
However, I am really curious to hear the general response, thoughts, and opinions.
Update (9/17): Fixed the sample markup (I forgot the <page> container tag!)
Posted on Friday, 9/16/2005 @ 11:17 AM
| #
ASP.NET