This scenario repeats very often in my case. I think about some architectural problem for a longer time sitting in front of the computer, staring at the code, project structure, reading wise articles about design patterns, but the solutions come to me in the toilet...
Maybe it wasn't so obvious to me, because I'm working on a pretty large project targeting different devices and generally speaking, models and controllers have been put in a common library, while views remain in the separate application projects. Maybe this threw me off centre.
Anyway, the solution is simple and quite logical I think:
- I'm not gonna use data attribute of the pushView() method to feed the list, regarding to my example.
- I will create a controller instance in the view and call its getData(filters:Array) method on 'refresh' click.
- The view is now dependent on the controller, so the project is no more as loosely coupled as I wanted, BUT:
- This can be easily done with an interface for example.
- How many times do we use the same view with different controllers...?
- We can open the view immediately, we don't have to wait for data.
- We can call controller's methods directly from the view.
- In most cases we need a controller when we open a view. When we pop the view, the controller is destroyed - less risk of memory leaks.
- Simple and logical.
In my example we can isolate two types of data:
- list items
- filter settings
Filter setting I would rather call meta-data (data that describe other data) and THIS is probably something worth to pass into view with pushView().
We can create a description of filters, sorting, pagination etc. from an url, default configuration, user preferences, anything and pass it to the view from outside. When the view is open, the user takes control on it. Does it make sense?
In this posts I have publicly straightened up my thoughts. Now it's childishly simple and natural, however I'm not gonna delete this discussion, maybe someone doesn't agree or have other ideas.
First of all forget about MVC and mobile being some special case in Flex - it's not.
MVC in it's basic form - ignoring established frameworks - is very simple.
The view displays data from one or more datasources - usually collections that allow the view to update when the content of the datacollection changes.
User interactions with the view should be communicated with events. Events decouple the view from any controllers wishing to act on those events.
A controller assigns the data sources used by the view to present it's data and listens to events generated by the view. The controller has access to the model and will manipulate it according to events received from the view.
That is basically how MVC works.
The controller essentially connects the view with the data it presents and modifes the model according to the users interaction with the view.
The view knows nothing about the controller.
That is the core of MVC with Flex.
Hi, thank you for the replay. I'm glad that despite my long posts you took up the topic.
You said that controller should be informed about user actions through events. I agree in 100%, but I don't know how to implement this in a mobile application in an elegant way.
In desktop projects we can create an instance of a view by ourselves and we can listen for its events. In a mobile application ViewNavigator creates view instances for us and doesn't expose them, so the data argument of the pushView() seems to be the only way to communicate views and controllers.
Technically it's not a problem, but it means that we have to dispatch events on model from view and handle them in the controller or to create additional, artificial properties in the model reflecting user interaction and listen to their changes- I don't think it's a nice solution, even if we wrap pure data in some structure of higher abstraction level.
Of course if we bind data to the view's controls we can also listen to data changes, but it will fire controller's methods on each property change, not on the 'refresh' button click.
Do you agree? Did I overlook something?