Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid circular notifications in MVC in Delphi?

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?

like image 983
jpfollenius Avatar asked Dec 04 '22 13:12

jpfollenius


2 Answers

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

like image 200
Tobias Langner Avatar answered Dec 31 '22 06:12

Tobias Langner


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.

like image 43
Deltics Avatar answered Dec 31 '22 07:12

Deltics