Posted At : November 28, 2006 6:36 PM | Posted By : todd sharp
Related Categories:
Flex,
CFCs,
ColdFusion
Subtitle: I'm a noob and I'm pretending like this is a theoretical example.
I'm going to borrow a page from the Jedimaster's playbook and present this scenario as a "puzzler" to the CF community. I know it will seem a little naive and noobish, but hell - a lot of my posts show that I'm noobish and well, I really don't care. I always say if you're not going up you're going down - so I always try to gain more knowledge and if it helps someone else out there along the way then cool.
So here's the scenario: In my last post I shared a UDF that I had written earlier today that I plan to use to help me efficiently page through query results using a Flex datagrid. Bruce Phillips commented that he thought it would be interesting to try and recreate this functionality within the Flex front end with Actionscript. I started to reply in the comments, but decided to turn the issue into a whole new post. While his logic is valid in that it avoids recurring calls to the component, that idea wouldn't quite work in my scenario. Why wouldn't it work you may ask, well that's the noobish part. Let me give a little background to my application (without spoiling too much since it's still 'top secret').
Essentially the Flex application will deal with a potentially large dataset (for those in the OO crowd you could call this the 'gateway'). Since the dataset can grow quite large I planned to cache the data to improve performance. To do so, I created a query in my components instance and planned to cache the query in the instance data when the component is init()'d (onApplicationStart). My Flex app will interact with the component via a proxy component which will return the base component from the application scope. So far, so good. Now I have a query that can be returned to the Flex front end (and paged via the UDF I created). Finally, here's the part I still don't feel comfortable with. My component will have the standard CRUD methods for interacting with the dataset - not DAO's per se (because I just ain't that cool yet), but rather simple methods to add/update/delete items. My thought is that when the standard add/update/delete happens I could simply use some utility functions to add/update/delete the query in the instance data (yeah, that's the part you can laugh at). Doing so will keep the instance data 'live' and keeping it in the instance will ensure that the data is available to all active sessions upon there next call to the component.
If you're still with me - thank you ;). So what are my alternatives? Obviously I could create a refresh method and call it on A/U/D - but it seems like that would defeat the benefits of caching (if the cache has to constantly be updated).
Posted At : November 21, 2006 10:24 PM | Posted By : todd sharp
Related Categories:
Flex,
CFCs,
ColdFusion
I've finally found a little time to actually sit down and give some love to this blog. All of my free time lately has been spent writing code, but it's good to actually sit back for a minute and document some of my experiences. If you're a reader of my blog, you know that I've recently started working with Flex after spending about 2 years with Flash Forms. Don't get me wrong, Flash Forms are slick. I still have many applications built with Flash Forms that are up and running, but there's something inside me now that just wishes I could rewrite every single one of them in Flex 2. I feel like I've been writing Flex app's for years, even though I'm still very naive to much of it. Like someone recently said in a comment thread that I read today - much of what you will learn to do in Flex is very easy to implement - it's just figuring out how to do it that's the pain sometimes. The good part of this learning curve is that once you figure something out, it's usually so dead simple that it's very easy to remember. I could be wrong, but I don't feel like I'll look back in 6 months or a year at some of the MXML and AS3 that I'm writing and shake my head. The documentation is pretty solid and the Flex community is as generous as the CF community is in sharing learning experiences and code. With that in mind, I'll begin by sharing a little bit of my code from cfcFlexplorer.
To give a little background for those who are not familiar with the project, cfcFlexplorer is a tool for CFC instrospection and testing. Out of the box CF gives us a sweet function for component introspection: getMetaData(). So my initial goal for the project was simple - take a CFC and retrieve the metadata. Of course I decided to get a little fancier later on and add a navigation tree rather than force the user to type in the full component path, but that's beyond the scope of this post. My first tests for this application were performed by writing my component and testing it (ironic, don't you think?). If you're not familiar with the getMetaData function and what it returns for components, try this code snippet on your own server to check it out.
<cffunction name="getCfcMetaData" access="remote" output="false" returntype="struct">
<cfargument name="pathToCfc" required="true" type="string">
<cfset var theCfc = createObject("component", pathToCfc)>
<cfreturn getMetaData(theCfc)/>
</cffunction>
<!--- to test --->
<cfdump var="#getCfcMetaData("path.to.your.favorite.cfc")#">
You'll notice in the dump that the getMetaData function returns a structure. There are several keys in the structure, many containing misc metadata (go figure) about the component (such as the display name, hint, etc). Take particular notice of the functions key - it contains an srray of structures in which each method of that component is represented as a distinct element of that array. Now notice within any of the given components there is likely another array of structs - this one containing an element for each parameter (or argument) within the given method (or function). Seems pretty intimidating, no?
Watch how beautifully Flex and CF play together. For those experts, look away now if this seems obviously noobish. In cfcFlexplorer, there is a simple remoting call which populates the method grid with the functions in the metadata structure. Here's a quick look at the result handler for the remoting call that retrieves the metadata.
private function handleMethodGridResults(event:ResultEvent):void{
methodGrid.dataProvider = new ArrayCollection(event.result.FUNCTIONS);
}
There is a little more to this function - but this is the only part necessary to show for this post. The remoting call passes the metadata struct to this function, which simply sets the methodGrid's dataProvider to the functions array of structs. Note the reference to FUNCTIONS - since CF returns all caps, we have to refer to it as such in our AS. The only other thing going on here is the coercion (or casting) of the array of structs as an ArrayCollection. This is done to take advantage of the ArrayCollection class and it's ability to play nice with easy grid filtering.
So that's it - a simple grid populated with a simple remoting call. But wait - what about the parameters? How can we display those? Well, that's even easier. Since the parameters were also passed back in an array of structs, we can use that column of the methodGrid dataProvider as a dataProvider for the parametersGrid like so:
<mx:DataGrid id="paramGrid" width="100%" height="95%"
editable="true"
dataProvider="{methodGrid.selectedItem.PARAMETERS}">
<mx:columns>
<mx:DataGridColumn headerText="Name" dataField="NAME" editable="false"/>
<mx:DataGridColumn headerText="Display Name" dataField="DISPLAYNAME" editable="false"/>
<mx:DataGridColumn headerText="Required" dataField="REQUIRED" editable="false"/>
<mx:DataGridColumn headerText="Type" dataField="TYPE" editable="false"/>
<mx:DataGridColumn headerText="Default" dataField="DEFAULT" editable="false"/>
<mx:DataGridColumn headerText="Value" dataField="VALUE" editable="true"/>
</mx:columns>
</mx:DataGrid>
We're simply telling the paramGrid to use the methodGrid's currently selected parameters as the dataProvider.
That just about wraps up my first in depth post on Flex. Hopefully this will benefit others who are just getting started with Flex or inspire someone who is on the fence about trying Flex because it seems a little intimidating. As I said above, the learning curve can be a little difficult to overcome (and I'm still very much learning myself), but trust me - dig into the sample applications and really try to figure out what's going on and you'll see that it will all start making sense very quickly.
Posted At : November 10, 2006 11:45 AM | Posted By : todd sharp
Related Categories:
CFCs,
ColdFusion
I just added my riaForgeCFC package to RIAForge - wow, that's confusing ;). Essentially riaForgeCFC is a component that retrieves data about your RIAForge projects.
Currently there are two methods:
- getProjectInfo returns a query containg a row for each of your RIAForge projects. (pass in the individual project name)
- getBlogInfo returns a structure of your RIAForge blog rss feed including a query of your latest posts.
Future support for forum RSS feeds will be added.
To use riaForgeCFC, init the component like such passing the uid for your xml feed (see sample in zip):
<cfset riaForge = createObject("component", "riaForge").init(projectUid)>
And yes, I did clean up the code from my UDF yesterday. Obviously that method could have been simplified.
Check it out and download here http://riaForgeCFC.riaforge.org
Posted At : October 19, 2006 3:23 PM | Posted By : todd sharp
Related Categories:
CFCs,
ColdFusion
I was just working on a cfc on my dev server and had done quite a lot of coding between tests when I came acrossed a weird issue. Usually I test quite frequently when I'm developing, just in case I mess something up (quite a rare occurence since I'm perfect) but this time I was on a roll so I just kept coding. After building quite a few methods, I went to a test page that called that cfc and reloaded. What happened next was a little suprising. I got nothing. No error, no debugging, no nothing. After about 10 minutes of banging my head against the keyboard (and a quick smoke break) I found the problem. See if you can find it too:
mycfc.cfc
<cfcomponent>
<cfset utils = createObject("component", "path.to.mycfc")>
</cfcomponent>
You got it, I moronically tried to instantiate my own cfc (instead of my utils.cfc) from within itself. I'm a bit surprised that this did not create any type of exception, but I guess that's what you get for a momentary lack of common sense.