Friday, July 27, 2007

Cairngorm ViewHelpers

http://nwebb.co.uk/blog/?p=84

== quote ==
The use of ViewHelpers in an architectural framework seems to be a bit of a grey area/hotly debated topic ( Jesse Warden summed up both of these things in quite an amusing way some time ago here). I don't have the breadth of knowledge to take one side or another, but I can explain how (and why) we are using them in our current project.

From what I can gather, many people see ViewHelpers as a way to locate, keep track of and simplify the use of Views. The rationale goes like this: when you work on a large project with quite a few people, and the team are creating lots of views, it becomes harder to keep track of the views and what they all do - the ViewLocator makes it easy to locate a particular view (using a descriptive String) and ViewHelpers themselves only expose public methods, thus simplifying working with views for people unfamiliar with the internals of that View.

That's not how we use them here.

Using ViewHelpers To Manipulate Existing Views (Without Updating The Model):
In a simplified view of Cairngorm, the Command class retrieves some info from a DataBase and updates the Model. The View is then updated through bindings to the Model. The Command should not know about the View.

So what happens when you want to do something to the View but you don't want to store anything in the Model? What if you simply wanted to make-visible some text in the View to say that all client-side data was up-to-date? You could set some flag/property in the Model, update that property and get the View to respond, but is that necessarily the right thing to do? Perhaps my simplified example could be better, but there are times where it doesn't feel right to be cluttering up the Model with properties that you don't feel are truly needed or rightly belong in the Model.

Sometimes it seems as if the Command should be able to manipulate the View, yet the Command should know nothing about the View, and you can achieve this with a ViewHelper. The ViewHelper sits in-between the two classes so that the Command and View are no-longer tightly coupled. The Command uses the ViewLocator ( a Singleton) to find the ViewHelper, and calls methods on it which in turn call methods on the View.

Note: To me, the notes in the Cairngorm ViewHelper class sound like they are backing up this as a valid use of ViewHelpers.

Using ViewHelpers When Creating Popups:
Let's say that a user needs to see some information (from a database) in order to make a decision about how many "widgets" to create. You are interested in the user's input (i.e. how many widgets he/she wants to create) but you don't want to store all the retrieved information in your application's Model - you are happy to discard it.

In other words, you want to generate a View (a pop-up window) from a Command. Here is an overview:
The Command would run, retrieve some info from the database and generate a pop-up window. The user would use the data to make a decision about how many widgets to create and enter a value in some input field. When he/she presses the "submit" button on the pop-up window, you remove the pop-up and return the input-value back to the Command. The Command then updates the Model with this value and the main View is updated accordingly via bindings.

Once again, this can be achieved using ViewHelpers without breaking the rule about letting the Command know about the View ( in much the same way as described above).

Using ViewHelpers When Adding Listeners To Popups:
Supposing for a moment that you did let your Command directly create your View... another problem with pop-ups that you may encounter, would be that they probably don't exist at the time you want to add any event-Listeners to it. You can try creating the pop-up first and adding the listeners upon creation, but that's not great.

The ViewHelper is a great place for putting an event-proxy. Extend the class and add the proxy functionality.
Now, rather than the Command listening to the View (which may not even exist, in which case you'll get a "null" error), you listen for events as if they were dispatched from the ViewHelper:
i.e. myViewHelper.addListener ("evtName", someFunc);

One way of coding this could be that when the Command tries to add a listener to the ViewHelper, you take all that info, wrap it up in an object and store it within an array on the ViewHelper.
As soon as the ViewHelper has created the View, it uses that information to add event listeners (between itself and the View). When an event is dispatched from the View it calls the method on the ViewHelper, which in turn calls the corresponding method on the Command class.
Okay, well there are my thoughts on ViewHelpers.
It would be great to hear your opinions (and alternative suggestions) for achieving these types of interactions within a Cairngorm app. Please feel free to leave feedback and add to the already raging debate about ViewHelpers

No comments: