Recursive MVC?


Here’s a sketch of what my brain is kicking around.

I want the body of my application to behave like a Swiss Army Knife – one that can be customized with any number or type of blades. In this case, each “blade” would be its own Flexy/AIRy module kind of thing.

I will write an interface on the SWAK body, that describes how to attach as a ‘blade’. The my gut tells me, each blade should implement MVC on its own, somehow. Against…. which model? Which controller?

And what if each blade want to contain… smaller, sub-blades?

Stay tuned.

Thoughts about the View.

Sometimes, I am the kind of learner that has to read the same paragraph over and over again before the main idea penetrates my skull and takes root.

Here’s a perfect example:

“The view gets the PM injected and binds data from it and delegates all interactions (events) to the PM.” (http://swizframework.jira.com/wiki/display/SWIZ/Presentation+Model)

A few lines of example code follow. I guess maybe the key lies in this little nibblet:

<s:Label includeIn="detail" text="{model.selectedItem.title}" />

… where ‘model’ is the bindable, injected class. After staring at this page and re-reading it a number of times – and, more importantly, writing some proof-of-concept code – it’s finally taken root is and growing as a concept in my mind.

I’ve said it before: it’s not like I’ve written any books about Object Oriented Programming, nor do I have deep experience with Cairngorm or Spring. Terms like ‘Service Locator’ and ‘Business Delegate’ aren’t part of what I usually talk about or deal with.

I’m somewhat closer to the glass, and I’m used to wiring up user interactions, and making sure that the application I’m building matches the designer’s comps as accurately as possible. My approach to Flash projects has always been to back Library assets with ActionScript objects where it made sense, and to have those objects communicate with my own, idiosyncratic implementation of micro-MVC patterns. I’ll use stand-alone classes that I call ‘controllers’ that react to events and change either the UI or the underlying application data layer or state. I rather abstractly think of the underlying application data as the ‘model’. This is what I have glommed from my reading OO books and conversations with other developers. (Some of them looked at me kind of funny, I admit, when I explained my system to them.)

My approach to Flex has been similar: back MXML components with code-behind objects, and have them communicate with ‘controller’ classes that make decisions about user actions, based on what the controller knows about the current application state. Swiz turns my world upside-down, and it’s taken some getting used to.

Here’s another page that will probably take me a while to fully digest: it’s Martin Fowler’s explanatory piece “Inversion of Control Containers and the Dependency Injection pattern.” This is required reading if you’re going in to the IoC biz (the way I am), and I have enough fluency in Java to muddle through the example code and have it make sense. But about halfway through the article, I got that familiar, sleepy, study-hall feeling I used to get in college. Now I know enough to realize that I need time to absorb, test, and go back to read more.

The View… the View… So. I am wondering about how to architect all the changes that need to happen to the program’s interface when my users interact with it. My old-school style would have me stashing tween classes here and there, in classes that i might have misnamed ‘controllers’ because they, well, controlled the interface. The code-behind mechanism gave me a comfy way to trigger events in the UI: someone clicks a button, the code-behind emits an event.

The Swiz PM approach does almost the same thing – but it’s more like this:

  • Create the view MXML
  • Inject your Presentation Model class into the XML (what I would have called a ‘controller’ in my thought)
  • Bind the MXML’s click or change actions to methods in the PM class that you injected

I get it – more decoupled. More encapsulated. I just need to get The Animator in my brain to understand where to stash all the tweens…

Follow-up to Aha!

OK, so check this out:

Without tweaking too much, I ran up against the limitations described by Spy 6: my PUT method was getting converted to a POST method. My immediate workaround was to use a URLRequest (and Swiz’s handy URLRequestHelper).

I tried twisting all the knobs I could find (admittedly, I was in a hurry), but I failed to get the HTTPService/ServiceHelper combination to give me any joy. Were I less lazy, I would probably dig in to the Swiz source to see if the issue was there, or perhaps (in a round-about way of testing deductions) try a PUT using HTTPServce without using ServiceHelper.

As it stands, using URLRequest is very straightforward:

[EventHandler("LoginRequestEvent.REQUEST_UPDATE_PASSWORD")]
public function handleUpdatePasswordRequest(lre:LoginRequestEvent):void {
  var updateURequest:URLRequest = new URLRequest("http://localhost/~jmj/projects/chb/fakelogin/fakeREST.php");
  var params:URLVariables = new URLVariables();
  params.username_put = lre.username;
  params.password_put = lre.password;
  updateURequest.data = params;
  updateURequest.method = URLRequestMethod.PUT;
  urh.executeURLRequest(updateURequest, handleUpdatePasswordRequestResult, handleURLFault, handleURLProgress, handleURLStatus, [lre.username, lre.password]);
}

 

An ah-hah! moment

OK, so, I am psyched to be on a project that will force me to stretch (once again), this time using technologies I’ve been itching to work with.

The top-secret mission that I can’t really divulge much about will be built using Adobe AIR and the Swiz framework, backing up to a RESTful service somewhere out there “in the cloud”. There’s a whole lot more to this project, but these are the parts of the project that concern me the most.

I’m going to use this blog to jot down some stuff that’s obvious to the already initiated. I run the risk of exposing my own ignorance, but hey, most blogs do that for most everybody, anyway.

Today’s revelation comes from the Adobe Help site, to wit:

“Use HTTPService components to send HTTP GET or POST requests and include the data from HTTP responses in a client application. If you are using Flex to build desktop applications (runs in Adobe AIR®), HTTP PUT and DELETE are supported.”

This is a good thing for me to know. Up until now, I’ve only done a few AIR projects, but mostly I’ve written straight-ahead Flex projects that didn’t need to leverage HTTP PUT or DELETE. I’m used to my own little organic code-compile-explode-debug cycle – and I was stressing about my misconception that Flex HTTPService “can only do HTTP GET and POST”.

Looks like I’m going to have to sit at the big kids’ table and compile and debug for AIR for this project… which is not news, but the good news is, now I know I have PUT and DELETE to work with.

(Insert bad pun using the word ‘rest’ here.)

 

Are you sure you want to leave this page?

Here’s an interesting problem, and a challenging one from a user experience point of view.

Ever try to navigate away from a page, and found yourself caught by a dialog box that says:

Are you sure?

This page is asking you to confirm that you want to leave – data you have entered may not be saved.

[Stay on Page] [Leave Page]

This is the work of the elusive ‘onbeforeunload’ event.

If I’ve got this right, ‘onbeforeunload’ came into existence courtesy of the .Net framework. You can look here to see the actual API description.

Here’s a little code example:

<script language="JavaScript">
  window.onbeforeunload = handleExit;
  function handleExit() {
    return "We'd like to send you a custom message before you leave!";
  }
</script>

Now, what happens when you leave a page with this kind of code in the head section of the document seems to be a matter of browser implementation. I’ve tried it a number of ways, and depending on how I’ve messed with (or messed up) the implementation, I’ve observed the following:

  • If your page exit function returns ANY value at all, it triggers the “Are you sure” confirmation box.
  • If your function returns a string, the browser will supposedly insert your string somewhere in the confirmation dialog box.
  • As concerns the above point, don’t always count on it. (See the final bullet point.)
  • There is a jQuery workaround to invoke action from this event. One can do it by binding the ‘beforeunload’ event to the window object.
  • As concerns the above point, there is some discussion about the merit of this approach
  • However, the jQuery API for bind() states: “The beforeunload event is supported cross-browser in jQuery 1.5.1 and 1.6+, but is not supported in IE for jQuery 1.5.2 due to a regression. “
  • Caveat emptor. This event is not part of the W3 Standards spec, so Opera doesn’t even bother with it, for example.

In addition to all the murk surrounding this event, there’s a religious war brewing just under the surface. Scratch only a little deeper and you’ll find folks who are cheesed off by the very idea that an architect or designer would want to interrupt someone from navigating away from a page. I’ve had those moments, especially when I’ve stumbled into some shifty kind of site that doesn’t want to let me go without yielding my email address. On the other hand, there have been a few times where I accidentally hit the back button or a link, and this catch-all prevented me from losing 15 minutes worth of form-filling work.

The real disappointment is that, after a long day of researching this topic, I’ve come to the conclusion that there’s no way to style the confirm box in any way. As developer, I am powerless to control the wording of the message nor what the buttons are labeled.

The workaround that occurs to me is to come up with my own confirm box (using the confirm() method) by somehow interrupting the navigation flow in the middle of the ‘onbeforeunload’ event handler. The logical problem is – I can’t return anything (or else I’d spawn another confirm box). So, I’m kind of stuck.

I know. A cliffhanger. Stay tuned – or better yet send me any ideas you might have. (Not through this blog tho.)

Some screen grabs:

Chrome:

Firefox:

Safari:

You’d think that it would work.

The mind is a funny thing.

Being a reasonable guy, I thought that this kind of initializer would work in Javascript:

myMultiDimensionalArray = [][];

Makes sense, right? Empty multi-dimensional array. Well… I’m not having a lot of luck with that. I don’t think JS knows what to do with that second empty bracket.

So, the lesson learned here is: you have to do things the slightly harder way, which is to initialize your second dimension after you’ve initialized your first. The basic pseudocode is this:

var multiDimArray = new Array(10);
// outer loop
for (var i = 0; i < lengthOfFirstDimension; i++) {
  for (var j = 0; j < multiDimArray.length; j++) {
     multiDimArray.[i][j] = "Your content here";
  }
}

If you don’t know (like I don’t) how many groups of array you’re going to need, you’ll have to count them first, so that you can initialize the outer array. I just thought it through, and yes, that seems to be the only way to go at it.

Mind you, this is just for a standard multi-dimensional array approach, as in putting together a matrix. This is NOT how to go about making an associative array, necessarily.

Git with it. You are in the middle of a conflicted merge.

Well. Here’s how you might expect things to go for me, first time through my first Drupal engagement as a Drupal developer – not as “the Flash guy”. And I chalk it up to just getting used to the tool set.

On a previous project, I watched the Drupal folks over their shoulders, and realized in about three nanoseconds that they use git for their source control. I actually tossed my Flash files over the wall to them, and they handled all the commits for me, so I never got intimate with git.

So, here we go, it showtime! I’ve made some changes to a file… and of course I neglected to push the changes, so now my file is in conflict with the repository’s copy. I’m heading down the well-worn path of conflict resolution.

I found this handy post, which helped a little. I found this post more useful though.

What I did: I went to the command line and issued ‘git mergetool’. Mac OSX accommodated me by running opendiff.

It turns out that there was a code change in the file, that my architect made. This is actually cool! I’d rather have to step through this kind of issue now, before the heat cranks up and I’m under serious deadline and stress.

So, I had made the edits I wanted to make already in my IDE, then quit opendiff – and here’s what happened on the command line:

user_register.form.inc seems unchanged.
Was the merge successful? [y/n] y

Once I did that, I was able to push and pull. I’m up-to-date!

Note: I did not have to resort to the more drastic measures of doing a reset or re-adding the file in question. Whew!

 

 

Drupal – tossed in to the deep end

Hello, neglected little blog.

Well, I decided to once again try to dust off my writing chops and try to keep the blog updated, at least a little. If anything, I can make it a repository for my technical ramblings and migrations, sort of a historical document.

I began work last week on a non-profit site that’s written in Drupal 6. Most of the work I’ve done to date is… reading, reading, reading. Documentation, documentation, documentation.

Oh, yeah, and a lot of installation and configuration schtuff. Here’s one gotcha that got me: in my settings.php file in my Drupal installation, the ‘localhost’ part of my URL string wasn’t resolving. Once I put in 127.0.0.1, everything lit up (after an hour of head scratching). And yes, Virginia, my hosts file is properly config’ed. Need you ask?

What’s a real kick for me is the fact that I’m sort of back in that cool middle ground of being a “site admin” for my own machine – installing and revving up the whole LAMP shebang on Mac OSX – and switching my brain over to all the other front end technologies I’ve been steadfastly ignoring – to my own detriment.

Also a shout out to my architect. She is DA BOMB and so helpful and patient and positive and optimistic. Mad props to her.

OK. More geeky stuff to come.

Stats: MBP, OSX 10.6.8, 8 Gb 1333 MHz DDR3

Embedding fonts without the transcode error

Here’s one I struggled with for the better part of an afternoon and for an hour in the morning. I got things working though.

Point of order number one: the magic solution came from this page:

http://www.flexfreaks.com/forums/viewtopic.php?id=96

from which I quote:

go to your project properties (right-click on your project would be easiest), then go to “Flex Compiler”, then under “Additional compiler arguments:” add “-managers flash.fonts.AFEFontManager”.

Next, here’s my stylesheet. Notice that I created only one fontFamily, but pointed the different weights to different TTF files:

.standardLabelText
{
	embedFonts: true;
	fontSize:12px;
	fontFamily:embedDanna;
	fontWeight: normal;
}

Button, ComboBox
{
	embedFonts: true;
	fontSize: 10px;
	fontWeight: bold;
	fontFamily: embedDanna;
}

@font-face
{
    src: url("fonts/verdana.ttf");
    fontFamily: "embedDanna";
    fontWeight: normal;
    fontStyle: normal;
}

@font-face
{
    src: url("fonts/verdanab.ttf");
    fontFamily: "embedDanna";
    fontWeight: bold;
    fontStyle: normal;
}

I was then able to use states and transformations, and the labels on the HBox I was targeting no longer hung there grinning like Cheshire cats.

As an aside, let me ask you – why does it make sense to make a developer jump through hoops to learn how to accomplish this kind of thing? You’d kind of hope that Flex would be smart enough to send you an alert or error message or email or tweet that said “Hmmm, looks like you’re trying to transform a font that’s not embedded. I can help you with that.”

Recipe: how to auto-close idle connections

Requirement:

I want to close idle connections for some applications, and make sure that connections stay open 24/7 for other applications.

Solution:

Edit the <AutoCloseIdleClients> element in my Server.xml file – then add and configure <AutoCloseIdleClients> elements in my Vhost.xml or Application.xml files. Season to taste.

Background and Analysis:

Bear with me. I’m picking my way through this.

I ran up against a situation in my home-grown connection pooling application. I noticed that connected clients – including pool-to-pool connections – were disconnecting. I also noticed that I was exceeding the 10-connection limit on the developer version of FMIS, by the way. So, I decided to get to the bottom of the issue and find out whether the disconnects were caused by the server maxing out the connection allotment, or if they were caused by some sort of timeout.

Adobe book-and-verse is a little confusing on the matter of the timeout. The config-admin guide tells me that the timeout is disabled by default. But it also tells me that the default timeout is 10 minutes.  So, which is it?

A closer inspecton reveals that if one switches the default <AutoCloseIdleClients> by merely changing the enable attribute from “false” to “true”, then you will indeed enable a global 10 minute timeout – because the Server.xml as it ships sets the MaxTimeOut to 600 seconds:

<AutoCloseIdleClients enable="false">
    <CheckInterval>60</CheckInterval>
    <MaxIdleTime>600</MaxIdleTime>
</AutoCloseIdleClients>

All this seems pretty straightforward, I guess. But then again, the way the documentation is written, it makes it seem like there’s a 10-minute timeout lurking around even if <AutoCloseIdleClients> is not enabled.

I’m conducting an informal inquiry at the moment – I’ve got a bunch of clients connected to my pool They’ve been idle for about 30 minutes now. None have disconnected of their own accord – so I guess I can conclude that there is no 10-minute default lurking somewhere in the background. Enabled=”false” means enabled=”false”.

But it does raise the question for me: if I did want to enable an auto timeout for a client, but not for the pool, how would I go about doing that?

What I might try goes as follows:

Server.xml – flip AutoCloseIdleClients enabled to true. Maybe even give it a massive, healthy timeout value, say, 60 minutes. (Question for Adobe: other that enabled=false, is there a value for “infinity – and beyond”? How about -1?….)

Pool application: set AutoCloseIdleClients enabled to false in the Application.xml file. That way, the pool never hangs up its connections due to timeout.

Client application: set AutoCloseIdleClients to true, and feed it my timeout value in the Application.xml file.

In theory, this should work. Guess we’ll see…