« September 2004 | Main | November 2004 »
October 26, 2004
Flex in action
Want to see a new app out there that uses Flex? Check out the demo of BridgeWerx. Flex is shown starting around 1:30. Congrats to Clint and all the folks at 5by5.
Posted by mchotin at 11:12 AM | Comments (4)
Text Filtering through a lot of data
Check out new iteration::two member Daniel Harfleet's post on dynamic text filtering. A really nice example.
Posted by mchotin at 10:43 AM | Comments (0)
October 13, 2004
foo(Void) vs foo()
Sometimes the benefits of a scripting language can come back to bite you in the rump :-) One thing that I've seen a lot of recently is the practice of declaring a function to have a single parameter: Void. The intention here is to indicate that the function takes NO parameters, a feature that other languages sometimes support. However, in ECMAScript (and thus ActionScript) it does NOT have that meaning. In fact, the compiler instead declares a local variable called Void! You can debate all you want about how wrong or right this is, but it's the way the language is designed.
Despite some of the additions to the language in AS2, ActionScript is still a scripting language and still allows you to pass a different number of parameters than what is declared in the function signature. In Flex we added some compiler checking to make sure that if you declare a variable or function that is already declared in the superclass, the type or signature matches between the two. This is to help prevent developers from accidentally overwriting a variable they didn't know existed in the superclass. However it also catches something like our (Void) problem. All shipped Flex code does not use the (Void) convention. If you then override a function and use that convention (which may have been done a lot in in the V2 components with MX 2004) you will see the compiler give you an error about Void not matching the superclass type.
Not sure how clear this is but I hope it can be of some help.
Posted by mchotin at 05:52 PM | Comments (2)
October 11, 2004
Flex as a dashboard
We've put out a press release describing a dashboard pilot for the California Air National Guard .
Posted by mchotin at 02:56 PM | Comments (1) | TrackBack
October 06, 2004
Effective Enterprise Java
TheServerSide has posted a sample chapter from Effective Enterprise Java about state and data management within your J2EE application. While the book focuses on J2EE a lot of the concepts discussed apply to general application development. You'll also get a preview of some of the things I plan on talking about at MAX in a few weeks. The first section of the chapter talks about saving state in the HTTPSession and some of the limitations; it's practically an advertisement for some of the benefits of RIAs :-) It also discusses data loading techniques coming from a relational database. You'll recognize some of the issues from the large data discussions we've had.
Posted by mchotin at 09:07 PM | Comments (0)
October 05, 2004
Want to get in the bowels of Flex?
Roger Gonzalez, one of our principal engineers and a regular contributor to flexcoders has written an article that explains how the Flex linker and loader work to deliver your apps. This article is heavy on detail and not for the faint of heart, but useful for those with some Flex experience. It's especially interesting if you want to understand why I keep talking about dummy variables for linking in classes :-)
Read it here.
Posted by mchotin at 11:29 AM | Comments (0)
Show off your RIA coding prowess
Grand Central Communications is about using Service Oriented Architecture to integrate business processes. They're introducing a developer's network and as part of that are creating a developer contest where one category is best use of a rich client. Flex is all about rich clients, so if you think you've got some skills go ahead and enter!
More info here.
Posted by mchotin at 11:25 AM | Comments (0)
Free Non-Commercial/Non-Institutional Flex
Press Release
FAQ
Usage Scenarios
Posted by mchotin at 11:22 AM | Comments (7)
October 04, 2004
Using a proxy to detect changes to models
Someone recently asked how you might intercept changes on an object so that you could know when it is dirty and needs saving. The catch was that he wants to use binding to populate the object and doesn't want to put event handlers on his controls just for this monitoring. Finally, he wants the solution to be generic (meaning that writing your object to have setters and monitor its own dirty state is not acceptable).
I've written up one solution to the problem here, using a proxy object to pass changes through to the final object, and using the proxy as the indicator of when things are dirty.
import mx.events.EventDispatcher;
/**
* Dispatched whenever the proxy passes on a change to the destination. Event properties are:
* type: 'change'
* target: this proxy
* property: the name of the property changing
* oldvalue: the value before the property is changed
* newvalue: the new value of the property
* wasPreviouslyDirty: true if the isDirty flag was set BEFORE this property was set
*/
[Event("change")]
/**
* This class can be used to proxy changes through to another object. It is given a list of properties to proxy
* and will pass on any changes that are different than the value already set. In addition it will dispatch
* a 'change' event indicating that the property has changed. Finally it will mark itself dirty so that
* it can be queried as to whether anything has changed.
*/
dynamic class ChangeDetectingProxy
{
//these functions will be filled in during event dispatcher initialization
//they need to sit above the real fill-in so that it gets overridden
function dispatchEvent(obj : Object) : Boolean { return true; }
function addEventListener(event : String, handler) : Void { }
function removeEventListener(event : String, handler) : Void { }
//this makes us an event dispatcher
static function _SetupEventDispatcher_() : Object
{
var o:Object = ChangeDetectingProxy.prototype;
EventDispatcher.initialize(o);
return undefined;
}
private static var _sed_ = _SetupEventDispatcher_();
private static var _dependsOnEventDispatcher_ : EventDispatcher = EventDispatcher;
private var __propertyList : Array;
/**
* The object to which changes will be passed.
*/
public var proxyFor : Object = null;
/**
* Indicates whether this object has made any changes. It is useful if you want to monitor the
* saved state of the 'proxyFor' object. You may reset isDirty any time (though it will be set
* to true immediately after dispatching a change event).
*/
public var isDirty : Boolean = false;
[ChangeEvent("propertyListChanged")]
/**
* An array of strings representing the properties that this proxy will pass through.
*/
public function get propertyList() : Array
{
return __propertyList;
}
public function set propertyList(pl : Array) : Void
{
__propertyList = pl;
//for every property create a getter to return the proxied object's value and a setter
//which will pass the change through (only if newvalue != oldvalue) and dispatch the
//change event
for (var i = 0; i < pl.length; ++i)
{
var propname = pl[i];
//arguments.callee refers to the function itself and is a way to make sure that each function has its unique
//instance of the property name
var getter = function()
{
return this.proxyFor[arguments.callee.propname];
}
var setter = function(newvalue)
{
var pn = arguments.callee.propname;
var oldvalue = this.proxyFor[pn];
if (oldvalue == newvalue) return;
this.proxyFor[pn] = newvalue;
this.dispatchEvent({type: "change", property: pn, oldvalue: oldvalue, newvalue: newvalue,
wasPreviouslyDirty: this.isDirty});
this.isDirty = true;
}
getter.propname = propname;
setter.propname = propname;
var tmp = undefined;
if (this[propname] != undefined)
{
tmp = this[propname];
delete this[propname];
}
this.addProperty(propname, getter, setter);
if (tmp != undefined)
{
proxyFor[propname] = tmp;
}
}
dispatchEvent({type: "propertyListChanged"});
}
}
Using this class you can now create MXML like this:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml" xmlns="*" backgroundColor="#ffffff" marginTop="0">
<mx:Script>
function save()
{
//somehow save the model
cdp.isDirty = false;
}
function exit()
{
if (cdp.isDirty)
{
alert("You haven't saved your data, please do so before leaving.", 'Save Needed');
}
else
{
alert('Goodbye');
}
}
</mx:Script>
<mx:Model id="mod"/>
<ChangeDetectingProxy id="cdp" proxyFor="{mod}">
<propertyList>
<mx:Array>
<mx:String>name</mx:String>
<mx:String>street</mx:String>
</mx:Array>
</propertyList>
</ChangeDetectingProxy>
<mx:Binding source="nameInput.text" destination="cdp.name"/>
<mx:Binding source="streetInput.text" destination="cdp.street"/>
<mx:Panel title="ChangeDetectingProxy Demo" id="p">
<mx:Form>
<mx:FormHeading label="Change an input and press exit to see how it works"/>
<mx:FormItem label="Name">
<mx:TextInput id="nameInput"/>
</mx:FormItem>
<mx:FormItem label="Street">
<mx:TextInput id="streetInput"/>
</mx:FormItem>
</mx:Form>
<mx:HBox>
<mx:Button label="Exit" click="exit()"/>
<mx:Button label="Save" click="save()"/>
</mx:HBox>
</mx:Panel>
</mx:Application>
Which in turn will produce a Flex app like this:
Posted by mchotin at 04:08 PM | Comments (5)