I am trying to use the Model-View-Controller pattern in a small application. The model contains some data and a selection like this
TModelSelection = record
CurrentItem : TItem;
end;
TModel = class
public
property Items : TList <TItem>;
property Selection : TModelSelection;
property Subject : TSubject <TModel>; // Observer pattern
end;
Now I have a tree view that observes the model. If the user selects an item in the tree view, the model selection should change.
The problem is that I run into problems with circular change notifications: I change the model selection in the tree view's OnChange event. This causes the tree view to update its selection (since the selection can also be changed by other parts of the application), which again triggers the OnChange event and so on.
How can I avoid this problem?
notify only on true changes.
Or use a flag to disable updates during updates.
procedure OnChange(...)
begin
if FChanging = false then
begin
FChanging:=true;
... do updates
FChanging:=false;
end;
end;
with FChanging being a member variable of type Boolean
A classic problem with MVC - when does a change in the view affect the model and when does it merely reflect the model?
This should be dealt with by the controller - if it isn't handled by the controller then you don't really have an MVC implementation but just an MV with controller logic embedded in and distributed throughout the interactions between the Model and the View.
When the user interacts with the View the View (treeview control) should notify the Controller which in turn updates the model.
When the Model is updated it should notify the Controller.
In that scenario, the Controller is already aware that is it updating the Model and so can disregard certain notifications that it would otherwise pass on to the View.
The biggest problem you face is that the controls used in your View are not ideally designed for use in an MVC implementation. Clicking in a treeview changes the selection in the treeview control (View) itself. In an MVC ideally what you want it to do is instead notify the Model (via the Controller) that the selection is required to be changed to the clicked item.
So the Model Selection state changes and the Treeview is notified. No View should ever assume that it already knows what it is doing to the Model.
The Treeview Selection State is then always only ever a reflection of the Model state.
But without doing some work in the user interface controls to create this distance between control state and underlying model state you are just going to have to struggle with work arounds.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With