My Feedback: ASP.NET AJAX Roadmap
Dave Ward had another great post this past week. He took the time to not only read the ASP.NET Ajax Road Map document, but he also wrote up a post outlining what he thought about it. So I thought I would join Dave's efforts and throw in my 2 cents as well. Of course, most of this post will not make too much sense if you aren't familiar with the Road Map document. So if that's you, here is what I recommend reading (in order) ...
- ASP.NET Ajax Road Map
- The feedback forum
- Dave's Post: The Future of ASP.NET AJAX (make sure you include the comments)
- Bertrand Le Roy's post (really only the comments are important)
My Comments ...
My goal is to be direct without being rude, lets see if I can do it.
$query
- Any plans on providing an extensible selector engine? If you have to go through all of the work to implement CSS 2.1 and 3.0, it would be cool to let developers hook into this engine and extend it.
- Do you have any idea on what operations will be available on the collection returned from $query? From the example provided, I can see addHandler, setStyle and create will be there, but I would really love to what else is available. Also …
- I would like to see helper functions for each events. I find it more readable to replace addHandler with $query(‘input’).click(function(){ //do something }); I know this might seem nitpicky, but I think it is this type of thing that makes the jQuery API so easy to work with.
- // I like this ...
- $query('input').click(function(){
- // do something
- });
- // better than this
- $query('input').addHandler('click', function(){
- // do something
- });
- I like the terseness of the jQuery API. You don’t see stuff like setStyle(). It would just be style() and all of the following would be possible. Again, probably trivial, but IMO the stuff that keeps the JS files nice and small and the API a breeze to work with
- // get the width of the first matched input element
- var width = $query('input').style('width');
- // set the width to zero
- $query('input').style('width', 0);
- // set the width and height
- $query('input').style({width:0, height:0});
- // set the width and height
- $query('input').width(0).height(0);
$listen
- Can we get the same stuff for attaching behaviors to elements? For example, any TEXTAREA that gets added to the DOM with a class of ‘rich’ should always get the RichTextBox behavior applied to it. Or do I have to manage this stuff myself? I would like to attach these behaviors the first time the page loads on the client and then not have to worry about it again.
- I like how there is a single entry point to the jQuery features -> $. Any chance $listen could hang off of the wrapped set? So I could do something like this …
- // again, I would prefer this
- $query('input').listen('hover', function(){
- // do something
- });
- // over this
- $listen('hover', 'input', function(){
- // do something
- });
- Is the parameter order for $listen correct? Seems like $listen(query, event, fx) would be more consistent
Templates and Client Data Sources
- The templates look interesting. And the complex template example really does look complex ;) But I found it hard to provide any real meaningful feedback here because of the complexity of the features. This stuff seems really promising, any idea when we would be able to see examples of how a sample GridView/ListView could be replaced with a client side template/data source (sorting, paging, editing, etc...).
- Will client side templates be able to fire server side events? Could an input button contained in a client side template trigger a server side event handler?
- Will the 2 way databinding require the bound JS objects to implement the INotifyPropertyChanged stuff?
Animation
- Will we have access to the animation queue?
- This still seems too verbose ....
- // isn't this better ...
- $query('.sprite')
- .fadeIn(300)
- .animate({backgroundColor:'ff0000', fontSize:'2em'}, 500)
- .fadeOut(300);
- // than this?
- $query('.sprite')
- .animate([
- new Sys.Animation.FadeIn(300),
- {'style.backgroundColor':'#ff0000', 'style.fontSize':'2em'), duration: 500 },
- new Sys.Animation.FadeOut(300)
- ]));
Other Stuff …
- In my opinion, the thing jQuery has over ASP.NET AJAX and the Toolkit is its programming model. It so simple that newcomers can get up and running and author there first plug-ins in nearly no time. But, the interfaces provide the ultimate in flexibility (hooks for extending the selection engine, access to the animation queue, etc...) for the more experienced developers. It truly is elegant, simple AND powerful. Now compare this to the tutorial for creating an ASP.NET AJAX extender control. This tutorial has me writing server side code, a JavaScript behavior that is nearly 100 LOC, plus all of the plumbing that glues the two together. That's just too complex ...
-
I think the TargetControlID could use some rethinking. Again, the extender control tutorial provides a sample for adding highlighting to a control that has focus. Here is how you can tie the behavior to the TextBox ...
- <asp:TextBox ID="TextBox1" runat="server" />
- <sample:FocusBehavior runat="server"
- ID="FocusBehavior1"
- HighlightCssClass="MyHighLight"
- NoHighlightCssClass="MyLowLight"
- TargetControlID="TextBox1" />
I know I can now access the HighlighCssClass and NoHighlightCssClass properties from the codebehind, but this just isn't something I find myself doing very often. Plus, I often wanted to apply an extender to multiple elements. Imagine a form where I have 7 textboxes and I want every one to get this highlighting. Binding the extender control to a class or tag based selector would have been useful. I would have traded the server side access for that without giving it a second thought.
Also, I prefer to use the DataControlFields of the GridView and DetailsViews. It would be pretty cool if I could have attached the extender controls to these fields too ... Seems like class/tag based selection would help here too.
- I really think the ASP.NET AJAX needs a plug-in programming model. A good part of the JavaScript code I write does not require a full blown Sys.UI.Behavior. I just want to run a bit of code when some DOM event occurs.
- I know this is just meant as an example, but a good illustration of this is the FocusBehavior you can find in the asp.net ajax documentation. Here is the source for this behavior ...
- // Register the namespace for the control.
- Type.registerNamespace('Samples');
- //
- // Define the behavior properties.
- //
- Samples.FocusBehavior = function(element) {
- Samples.FocusBehavior.initializeBase(this, [element]);
- this._highlightCssClass = null;
- this._nohighlightCssClass = null;
- }
- //
- // Create the prototype for the behavior.
- //
- Samples.FocusBehavior.prototype = {
- initialize : function() {
- Samples.FocusBehavior.callBaseMethod(this, 'initialize');
- $addHandlers(this.get_element(),
- { 'focus' : this._onFocus,
- 'blur' : this._onBlur },
- this);
- this.get_element().className = this._nohighlightCssClass;
- },
- dispose : function() {
- $clearHandlers(this.get_element());
- Samples.FocusBehavior.callBaseMethod(this, 'dispose');
- },
- //
- // Event delegates
- //
- _onFocus : function(e) {
- if (this.get_element() && !this.get_element().disabled) {
- this.get_element().className = this._highlightCssClass;
- }
- },
- _onBlur : function(e) {
- if (this.get_element() && !this.get_element().disabled) {
- this.get_element().className = this._nohighlightCssClass;
- }
- },
- //
- // Behavior properties
- //
- get_highlightCssClass : function() {
- return this._highlightCssClass;
- },
- set_highlightCssClass : function(value) {
- if (this._highlightCssClass !== value) {
- this._highlightCssClass = value;
- this.raisePropertyChanged('highlightCssClass');
- }
- },
- get_nohighlightCssClass : function() {
- return this._nohighlightCssClass;
- },
- set_nohighlightCssClass : function(value) {
- if (this._nohighlightCssClass !== value) {
- this._nohighlightCssClass = value;
- this.raisePropertyChanged('nohighlightCssClass');
- }
- }
- }
- // Optional descriptor for JSON serialization.
- Samples.FocusBehavior.descriptor = {
- properties: [ {name: 'highlightCssClass', type: String},
- {name: 'nohighlightCssClass', type: String} ]
- }
- // Register the class as a type that inherits from Sys.UI.Control.
- Samples.FocusBehavior.registerClass('Samples.FocusBehavior', Sys.UI.Behavior);
- if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
- I know this is just meant as an example, but a good illustration of this is the FocusBehavior you can find in the asp.net ajax documentation. Here is the source for this behavior ...
And the same functionality can easily be written as a jQuery plug-in in a fraction of the lines.
- (function($) {
- $.fn.focus = function(options) {
- // build main options before element iteration
- var opts = $.extend({}, $.fn.focus.defaults, options);
- return this.each(function() {
- // add/remove the class as the element comes into and out of focus
- $(this).focus(function(){
- if(!this.disabled){
- $(this).addClass(opts.highlight);
- }
- }).blur(function(){
- if(!this.disabled){
- $(this).removeClass(opts.highlight);
- }
- });
- });
- };
- $.fn.focus.defaults = {
- highlight: 'highlight'
- };
- })(jQuery);
The example above really just ties a very small bit of JavaScript to a couple of event handlers. It would be great to have plug-in plumbing in the next rev to make doing stuff like this easier.
- On sort of a related note, I think the existing existing ASP.NET AJAX and Toolkit components are too verbose and too OO (yes it feels weird saying that). Some of the things that bother me are ...
- The uber long namespaces. Stuff like Sys.UI.DomElement.containsCssClass is just too long. Is requiring so many namespaces to organize the library a sign that it has become too large?
- Having multiple entry points. I like how everything in jQuery starts with $(). Its simple.
- All of the code required for the property getters and setters. Where am I seeing the value from calling raisePropertyChanged?
And I just have to wonder if having such a rigid and verbose programming model is the right choice for a client side AJAX library.
- I don’t want to pay for features I don’t plan on using
- I have never use the RoundedCorners and DropShadow features of the ModalPopup control, but there is no way (that I know of) for me not to pull these scripts down to the client. I like how jQuery is progressive. If the metadata plug-in is available, it will go ahead and use it. But if you decide not to pull it down, nothing will break and the widget/plugin is still usable. And for animations, just the real low-level plumbing and most often used parts of animation components are bundled in with jQuery's core. If you choose to animate colors, you can add the color animation extensions.
- I like how jQuery doesn't pull down any extensions to the String/Number/Date prototypes.
Conclusion
Well, I tried to be blunt without being rude - I truly hope that I succeeded. I hope I don't come off as angry or anything, I just have spent a lot of time with ASP.NET AJAX and the Toolkit and think that these are the things that I would want changed for vNext. And just like Dave said, I am not an MVP, or an Insider, I am just a regular dev that really wants Microsoft to nail the next version of ASP.NET AJAX. Good luck guys!
That's it. Enjoy!





