What I like about Atlas: Behaviors
So I've been hacking away with Atlas now for the better part of two months. As I got to playing with it, what I really focused in on was behaviors and control extenders. You can really improve a website's experience without much pain by using them.
A behavior is a class written in Javascript that kind of attaches itself to a running element in the browser.
A control extender is an ASP.NET server-side control that helps you connect a control on the page to your behavior. I'll talk about those later.
Behaviors are cool mostly because the Atlas script framework is super sweet. I've always hated programming in script for a couple of reasons. One of them hasn't gotten any better, so far at least, and that's that the tools experience around script is pretty weak. No compiler, a minimal debugger, almost no Intellisense, etc. The other issue is that it's just kind of scattered all over the place. It's in random blocks through the HTML file, or in quotes as attribute values of tags or whatever. Ick.
The script framework allows me to do away will all of that. The framework puts some structure around the world, so even without the tooling, I'm able to do things much more effeciently.
Imagine a basic behavior that pops up a confirm box when you click a button. To do this in script, it's something like:
<asp:Button ID="Button1" runat="server" Text="Button"
OnClientClick="return confirm('are you sure?');" />
Which isn't too bad but it's error prone, completely non-debuggable, and I have to sprinkle it all over my website, even though it's not a lot of code, and if there's something wrong with it (e.g. the above doesn't work in Mozilla), it's tough to change. Of course, I could break the functionality out into a, er, function, but it doesn't greatly improve things.
Atlas gives me a nice way to handle this with a behavior. Now, the following is a lot more code, but it's boilerplate, and it's maintainable and easily extensible if I decide I want to add more features. The part that's specific to this guy is in bold:
Type.registerNamespace(
'MyNS');
MyNS.ConfirmButtonBehavior =
function() {
MyNS.ConfirmButtonBehavior.initializeBase(
this);
var _ConfirmTextValue;
var _clickHandler;
this.initialize = function() {
MyNS.ConfirmButtonBehavior.callBaseMethod(
this, 'initialize');
// Initialize member variables
_clickHandler = Function.createDelegate(
this, this._onClick);
// Attach event handlers
this.control.element.attachEvent("onclick", _clickHandler);
}
this.dispose = function() {
// Detach event handlers
if (_clickHandler) {
this.control.element.detachEvent("onclick", _clickHandler);
_clickHandler =
null;
}
MyNS.ConfirmButtonBehavior.callBaseMethod(
this, 'dispose');
}
this.getDescriptor = function() {
var td = MyNS.ConfirmButtonBehavior.callBaseMethod(this, 'getDescriptor');
td.addProperty(
'ConfirmText', String);
return td;
}
this._onClick = function () {
event .returnValue = window.confirm(_ConfirmTextValue);
}
this.get_ConfirmText = function() {
return _ConfirmTextValue;
}
this.set_ConfirmText = function(value) {
_ConfirmTextValue = value;
}
}
MyNS.ConfirmButtonBehavior.registerSealedClass(
'MyNS.ConfirmButtonBehavior', Sys.UI.Behavior);
Sys.TypeDescriptor.addType('MyNS
', 'ConfirmButtonBehavior', MyNS.ConfirmButtonBehavior);
So, yeah, it's more code but it's nice and structured. There's an initialize method where I set up my state, a dispose method where I tear it down, an _onClick method where I work my magic, and a couple of property accessors. And if I want to add some functionality or some logic to run, I've got well-structured places to do it. What's more is that this won't collide with other behaviors. If you've got something else that you want to happen when a button is clicked, it will co-exist peacefully with this behavior. Not so with the old script method.
So how do you use this on a web page? Well that's a little trickier, and I'll give you a hint that extenders help. But without extenders, here's how I hook it up:
1) Add a ScriptManager to my page
<
atlas:ScriptManager ID="ScriptManager1" runat="server"/>
2) Add a control that's going to be the target of this behavior. We'll add two.
<
asp:Button ID="Button1" runat="server" Text="Button" />
<asp:Button ID="Button2" runat="server" Text="Button" />
3) Add the xmlscript to hook the things together.
<
script type="text/xml-script">
<page xmlns:script=
"https://schemas.microsoft.com/xml-script/2005" xmlns:MyNS="MyNS">
<references>
<add src=
"ConfirmButtonScript.js"/>
</references>
<components>
<control id=
"Button1">
<behaviors>
<MyNS:ConfirmButtonBehavior ConfirmText=
"Click Button1?"/>
</behaviors>
</control>
<control id=
"Button2">
<behaviors>
<MyNS:ConfirmButtonBehavior ConfirmText=
"Click Button2?"/>
</behaviors>
</control>
</components>
</page>
</script>
And boom, you've got your behavior hooked up, and you can hook that one behavior up to as many controls on the page as you like. Much nicer.
Again, extenders make this experience much nicer. I'll talk about those in a post soon.
Comments
- Anonymous
March 17, 2006
Thank you!!!!
I needed something simple and easy to follow to get my hands around this.
I can't attend Mix this year - but I look forward to hearing what comes out of it.
Glad to see you are working with Scott Guthrie - I follow his blog as well.
Just fyi: what you have posted here goes a long way for me to understand how the Atlas framework will work.
Thanks again - fantastic! - Anonymous
March 17, 2006
Let me add one note:
Is there anyway to get intellisense for the Atlas javascript portions from within VS 2005? - Anonymous
March 19, 2006
In future releases will there be as much boilerplate code to be written, or will you be abstracting some of this away? - Anonymous
March 20, 2006
Thanks for your comments!
In order...
1) Yes,I'm glad to be working with Scott as well!
2) So, as I mentioned, we've got work to do for that Atlas/script tools story. And one part of this is getting Intellisense support in there, but I actually don't know what the current plan is. With Javascript being a late-bound (e.g. weakly typed) language, statement completion is really tough, because it's pretty hard to statically figure out what an object is in order to list it's operations. But there's some smart people running around and hopefully they'll improve that story.
3) Keep any eye out for a post I'll be doing today (hopefully) that addresses your question exactly. In sort, no you won't have to write all this code! - Anonymous
March 20, 2006
Shanku (Atlas/ASP.NET PUM)&nbsp;just finished giving his Atlas talk where he went through the major parts...