MVC - who decides what to do if there was no content? - model-view-controller

When loading a page that lists for example events from a DB, but there are no events going on right now, who's decision should it be to show a message "sorry no events going on right now..."?
Should the model check if the array with events is empty, and call the view that holds this message as static content
Or should the view check if the array with content is empty, and if so display a message that informs the user?
Or is this opinion based and it depends on personal preference?
If it is based on personal preference, what are some of the advantages and disadvantages of either method?
EDIT:
The same question could be applied to: We are trying to load an event, but the event is over, so it will say "sorry, this event is already over". Again: Model's choice or View's choice to say this?

View is the part of triad, which will be aware that there is no content, when said view request the list of active events from model layer and gets back nothing.
If you are looking at this in the context of PHP, then your view won't be observing the model layer and will have to initiate the request for data.
Also, if you actually send back completely nothing, then the same view should also set the response code to 204.

When to show which kind of message is obviously a choice of the view. The model shoudln't know anything about users reading messages but only about its inner state.
The actual question is, how does the view know when to decide about which message should be shown. There are mainly two ways I could think of:
The view polls the state of the model each minute/second/millisecond/when-user-clicks-button/whatever and updates the messages if needed
or
The model itself emits events when its state changes and the view listens to those events.
But, the model emitting an event saying "my state is changed" is something totally different from deciding to show a message to the user and both should be strictly seperated.

Related

Model-View-Controller: who notifies the View

The user-input is received by the Controller. The Controller manipulates/edits the Model.
The View can query the Model in order to obtain the new state for diplaying. The point I do not get is who actually notifies the View of changes? Because in the schematic overview, It seems that the Controller sends modification messages and that the Model also notifies the View of changes.
Even in the example, both notify the View. If the controller sends for example the position of the needle, why must the Model still notify the View?
[The figures are from the slides of our prof, so they are correct anyway]
It was becoming a bit confusing, so I googled to see what some leading authorities have to say, because Wikipedia and the first hits are not as good as they seemed to be.
Model. The Model manages the behavior and data of the application domain, responds to requests for information about its state (usually from the View), and responds to instructions to change state (usually from the Controller).
View. The View manages the display of information.
Controller. The Controller interprets the mouse and keyboard inputs from the user, informing the Model and/or the View to change as appropriate.
So it seems that the Controller notifies the View.
But it is important to note that both the View and the Controller depend on the Model. However, the Model depends on neither the View nor the Controller. This is one of the key benefits of the separation. This separation allows the model to be built and tested independent of the visual presentation.
And of course the Controller cannot be the only one who changes the Model. For that reason there are indeed some variations:
The passive model is employed when one Controller manipulates the Model exclusively. The controller modifies the Model and then informs the View that the Model has changed and should be refreshed. The Model in this scenario is completely independent of the View and the Controller, which means that there is no means for the Model to report changes in its state.
The active model is used when the Model changes state without the controller's involvement. This can happen when other sources are changing the data and the changes must be reflected in the Views. Because only the Model detects changes to its internal state when they occur, the Model must notify the views to refresh the display.
-> Explains the case.
Model does not have to necessarily notify the View - in that case you get a passive implementation of MVC, see wikipedia.
The model can for example compute something in the background, e.g. it could be computing positions of particles in a particle system and here and there it could notify the view to update itself - i.e. the push model which is often more efficient than polling the model from the View.
For example before WebSockets and Comet, it would be always the Web view notifying the Controller which would poll a Model and render a new View. With WebSockets or Comet you can have the Controller notifying the View.
In any case, there are myriads of spins on implementing MVC, it's not set in stone and of course you can adapt it to your use case.

Backbone.js Use View to Manipulate Another View

My question is mostly conceptual about Backbone.js, but I can mock up some code if my question is unclear.
Consider a case where I have 2 sections on a website. A list of items as one view and another view that has a dropdown to select how the list of items should be sorted. Obviously, the list of items is associated with a collection of models that stores the actual data that populates the list. But I'm unsure the best approach for triggering the collection to be sorted differently when the other view's dropdown changes. Should I be changing the actual order of the collection, or just render the view in the order that I want in the view?
Also, is it a good idea to use a model for the dropdown to keep track of the state of the dropdown, and bind the list of items view to that model so that I know when to rerender the list of items?
You could take several roads here. Here's a few:
Use a router. The router would hold your views, or at least the top-level view (cleaner), and your dropdown view would trigger a route change, which would pass the information along to the view. Best if you want clean URLs.
Make a pointer to the list view in the dropdown view. When the dropdown view receives the change event, it explicitly tells the list view to update. (IMO a terrible approach, but listed here for completeness.)
Back everything with models. (Like you suggest in your last question.) The dropdown view would be backed by a model, and the list view could bind to that model's events. (Again, the list view still has to know about the dropdown model—not ideal.)
Make an event manager. When your dropdown recevies a change, you trigger 'sort' and anything that cares can listen to that event. This isn't a trivial solution but isn't overly complex either. Your list view could then register its intent to listen to the sort event with the event manager, thereby abstracting the actual view inside the event manager and away from the dropdown view.
1 & 4 are effectively the same thing, just depending on whether you want a router or not.
Basically my heuristic with these sorts of scenarios is "nothing should know about things it doesn't need to know about." Applied here, that means that your views shouldn't know about each other.

Cocoa-Binding : Submit changes manually?

in my application I have a NSTableView bound to an ArrayController (arrangedObjects). I also have a Details-View (just some textfields) bound to the same Controller (selection).
Now every time I edit a textfield the changes are automatically send to the ArrayController and the Table changes as well. How can I avoid this? What I want is a "Submit-Button". Changes on the data should only be send to the controller when I press the button and not automatically every time I do an edit.
There are really two answers to this question. The first is more philosophical: in most cases you want updates to the model to occur instantaneously. For the most part users shouldn't have to be bothered with saving, committing, etc. changes the make. Binding's pervasive integration with the NSUndoManager means that anything the user does can be undone (or should be undoable). All user actions should be "low risk" such that making a change and then undoing does not cause unnecessary "harm" to the user's data or the application state. If you're using Core Data for your model layer, you can always roll-back or save a set of changes programmatically using the NSManagedObjectContext's methods. Unless there's a really good reason why the user needs a "Submit" button, don't put one in. In line with this philosophy is Gmail's "Undo Send" functionality. Even sending an email should be undoable (within reason).
The second answer is more practical. Of course there are situations where you're dealing with a backend system that isn't as forgiving of undos as Cocoa. In that case, the best option is to create a temporary model object that serves as the model for the UI (think a View-Model in the Model-View-View-Model (MVVM) architectore). When the user submits the changes, you can copy the temporary model object into the persistent model. In Core Data, you can use an in-memory persistent store backing a separate managed object context to hold these temporary instances and then merge changes from this temporary context into your main context on submit.
This might be enough:
Select the text fields in Interface Builder.
Switch to the "Text Field Attributes" pane of the Inspector panel (hit Cmd-1).
Change the Action popup box to "Sent On Enter Only".

MVC design question for forms

I'm developing an app which has a large amount of related form data to be handled. I'm using a MVC structure and all of the related data is represented in my models, along with the handling of data validation from form submissions. I'm looking for some advice on a good way to approach laying out my controllers - basically I will have a huge form which will be broken down into manageable categories (similar to a credit card app) where the user progresses through each stage/category filling out the answers. All of these form categories are related to the main relation/object, but not to each other.
Does it make more sense to have each subform/category as a method in the main controller class (which will make that one controller fairly massive), or would it be better to break each category into a subclass of the main controller? It may be just for neatness that the second approach is better, but I'm struggling to see much of a difference between either creating a new method for each category (which communicates with the model and outputs errors/success) or creating a new controller to handle the same functionality.
Thanks in advance for any guidance!
My preference would be to create triplet Form-Controller-Model for every form displayed to the user. Whenever user clicks on 'Next' button on a form its controller should talk to the back end manager which takes care of dispatching submit request to the next form in chain. Vice verse if 'Back' button is clicked. Last form has a 'Finish' button which will go to the manager and pass the last bits of information.
This will avoid inheritance, make your code more robust and testing of forms possible in isolation.
My preference would be to keep it all in one controller. It keeps all the relevant processes for filling out the application/form in one place, although I'm not sure how "massive" you're talking about. If you do decide to split it out, I would not subclass off of the main controller, but just make a handful of independent controllers, perhaps related by name for ease of use down the road.

Breaking event cycles in GUIs

When writing GUIs, I've frequently come over the following problem: Assume you have a model and a controller. The controller has a widget W that is used to show a property X of the model.
Because the model might be changed from outside the controller (there might be other controllers using the same model, undo operations etc), the controller listens to changes on the model. The controller also listens to events on the widget W and updates the property X accordingly.
Now, the following happens:
the value in W is changed
an event is generated, the handler in the controller is invoked
the controller sets the new value for X in the model
the model emits events because it has been changed
the controller receives a change event from the model
the controller gets the value of X and sets it in the widget
goto 1.
There are several possible solutions for that:
Modify the controller to set a flag when the model is updated, and not react to any events from the model if this flag is set.
Disconnect the controller temporarily (or tell the model not to send any events for some time)
Freeze any updates from the widget
In the past, I usually went for option 1., because it's the simplest thing. It has the drawback of cluttering your classes with flags, but the other methods have their drawbacks, too.
Just for the record, I've had this problem with several GUI toolkits, including GTK+, Qt and SWT, so I think it's pretty toolkit-agnostic.
Any best practices? Or is the architecture I use simply wrong?
#Shy: That's a solution for some cases, but you still get a round of superfluous events if X is changed from outside the controller (for instance, when using the command pattern for undo/redo), because then the value has changed, W is updated and fires an event. In order to prevent another (useless) update to the model, the event generated by the widget has to be swallowed.
In other cases, the model might be more complex and a simple check on what exactly has changed might not be feasible, e.g. a complex tree view.
The standard QT way of dealing with this and also the one suggested in their very useful tutorial is to make the change to the value in the controller only if the new value is different from the current value.
This is way signals have the semantics of valueChanged()
see this tutorial
Usually you should respond to input events in the widget and not to change events. This prevents this type of loop from occuring.
User changes input in the widget
Widget emits change event (scroll done / enter clicked / mouse leave, etc.)
Controller responds, translates to change in the model
Model emits event
Controller responds, changes value in widget
Value change event emitted, but not listened to by controller
Flags to indicate updaing work. You can wrap them in methods like BeginUpdate and EndUpdate.

Resources