elmishmodel-view-update

Equivalent of data binding model updates in Elm-style model-view-update


MVU State Changes

As I understand Elm-style model-view-update architectures, changes to application state follow the sending of a message that defines the updated state. The state here is immutable, so changes result in a whole new set of application state.

For example, in the below (taken from the Fabulous project) the Pressed message results in the state changing Model.Pressed to be true.

I believe the message would be sent as a result of the user taking an explicit action, such as clicking submit or save.

/// The messages dispatched by the view
type Msg =
    | Pressed

/// The model from which the view is generated
type Model =
    { Pressed: bool }

/// Returns the initial state
let init() = { Pressed = false }

/// The function to update the view
let update (msg: Msg) (model: Model) =
    match msg with
    | Pressed -> { model with Pressed = true }

/// The view function giving updated content for the page
let view (model: Model) dispatch =
    if model.Pressed then
        View.Label(text="I was pressed!")
    else
        View.Button(text="Press Me!", command=(fun () -> dispatch Pressed))

type App () as app =
    inherit Application ()

    let runner =
        Program.mkSimple init update view
        |> Program.withConsoleTrace
        |> Program.runWithDynamicView app

Data Binding State Changes

Let's say you have a model in WPF, perhaps, that implements INotifyPropertyChanged and uses data binding to attach your state to a user interface. So, the state here is mutable and will change over time.

As the user enters new values, the model is updated as a result of the data binding and without them explicitly saving or submitting. Because of this, any calculated values in the model will update as the user enters values. Here's an example of a model that updates an Age value when a new date of birth is entered.

public class PersonView: INotifyPropertyChanged
{
    private DateTime _birthday;
    public DateTime Birthday
    {
        get { return _birthday; }
        set
        {
            _birthday = value;
            PropertyChanged("Birthday");
            Age = CalculateAgeFromBirthday();
        }
    }

    private int _age;
    public int Age
    {
        get { return _age; }
        private set
        {
            _age = value;
            PropertyChanged("Age");
        }
    }

    void PropertyChanged(string property)
    {
        // Etc.
    }

    int CalculateAgeFromBirthday()
    {
        // Do you sums here;
    }
}

The Question

My question is whether there is an equivalent way in Elm style model-view-update architectures to create a user interface that updates these "calculated properties" as the user enters values in a similar manner to how a data bound view with a mutable model?


Solution

  • Let's say you have a model in WPF...

    If you want to use Elmish with WPF, then I recommend using Elmish.WPF. The repo contains many samples that are great for quickly understanding.

    My question is whether there is an equivalent way in Elm style model-view-update architectures to create a user interface that updates these "calculated properties" as the user enters values in a similar manner to how a data bound view with a mutable model?

    I see two ways you can do this.

    1. In your update function, in addition to updating to the newly entered data, also explicitly compute the derived data.
    2. In your binding, compute the derived data.