Does your Command call your View (tsk !) ?

Submitted by Falken on

Imagine a DataGrid. A DataGrid that is displaying Model.searchResults, but needs to start an effect and reset selectedIndex when the data changes

One approach maybe to follow a pattern than involves having the Command call a method on the View, and this view method takes charge of doing whatever else is needed.
This makes Commands more complicated and means Events have to have an extra 'view' property which is kept in the Command as a private variable.
The View then has to expose a public 'onCommandNameResult' method which the Command calls in onResult().

Having read http://www.adobe.com/devnet/flex/articles/blueprint_02.html[1] I think there is a better way to have the View respond to change in the Model (i.e. Command results) without needing this callback.

Flex 2 and 3 ship with something called 'ChangeWatcher' which will call a method when a property on an object changes.
In the above case of a DataGrid, you could tell ChangeWatcher to call a function when 'Model.something' changes, and this will work just as well as a callback from the Command, but feels a lot nicer.

Apart from a minor change in your components set up code, the 'onComandNameResult' need not be changed from the alternative approach, if you've been doing that (hands up ! :-) ).

private function creationCompleteHandler(e:*):void{
ChangeWatcher.watch(model,"searchResults",onSearchResultChange);
}

private function onSearchResultChange(e:*):void{
resultDataGrid.selectedIndex=0;
fadeFx.play();

if (model.searchResults.length ==0){
Alert.show("No results returned","Information");
}
}

[1] See the final page here for an unrelated discussion about doing (Cold)Spring-like dependency injection in MXML - hint: it's easier than you think

Sections

You can also have your View have a Binding target a setter function. Whenever the binding fires, your setter can do magic; less code, too.

I'm not sure what you are getting at.
Do you mean the View would have a public Bindable property (implemented as 'public function set searchResults(a:Array):void') for the search result, and the Command would set this (using the deprecated ViewLocator ?) ? If so, that seems just as bad as a callback in the Command, except you don't need the property on the Event.
If you mean the Model would have the set Method, how does the Model call the method in the View ?

Tom

No, Commands shouldn't know about View's. Rather, the Mediator; the dude who binds the View with his Model, set's this. So, the View would like something like:
protected var __sr:ArrayCollection;

[Bindable]
public function get searchResults():ArrayCollection
{
   return __sr;
}

public function set searchResults(val:ArrayCollection):void
{
   __sr = val;
   resultDataGrid.selectedIndex=0;
   fadeFx.play();
 		
   if (model.searchResults.length ==0)
   {
	Alert.show("No results returned","Information");
   }
}
And the Mediator who set's him up (Application.mxml, the hosting form, whoever) can go: <YourResultsView searchResults="{Model.instance.searchResults}" /> Key difference here is that the component itself has no clue about the Model; making it more portable. The Mediator who sets him up controls when and where that data comes from. Typically in smaller apps, yeah, that's the Model. However, in larger apps, that could be yet another variable. Additionally, this allows you to use the View in multiple places; as long as it's an ArrayCollection, good to go. Make sense?

Submitted by Ken Lejnieks (not verified) on Thu, 01/17/2008 - 19:08

Permalink

Not sure if this helps, but... http://improviseadaptovercome.com/2007/10/18/talk-to-your-view-through-your-command/ basically a walk through on having your command talk to your view, when and why etc...

Submitted by Daniel Harfleet (not verified) on Fri, 01/18/2008 - 10:27

Permalink

Can I suggest you take a look at this excellent series of blog entries by Alex Uhlmann on Cairngorm. Alex was part of the iteration::two team who originally built Cairngorm (ref) and has experience of using it on a daily basis in real world projects. Daniel