Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A correct way to handle multiple command (from buttons) with Gjallarhorn

There are a couple of buttons on the window and I try to find good approach to handle commands.

For example:

I have to perform some actions:

type Action = 
    |Show
    |Open
    |Input
    |Change
    |Statistic

translating this to the xaml will be:

<Button Command="{Binding ShowCommand}" />
<Button Command="{Binding OpenCommand}" />
<Button Command="{Binding InputCommand}" />
<Button Command="{Binding ChangeCommand}" />
<Button Command="{Binding StatisticCommand}" />

a bit playing with library I found two ways to do it without annoying verbose

1. Use Observable.merge

Binding.createMessage "StatisticCommand" Statistic source
|> Observable.merge (Binding.createMessage "InputCommand" Input source)
//|> Observable.merge ... and so on
|> Observable.subscribe (performAction model.Value)
|> source.AddDisposable

2. Create generalize message

type GeneralMessage = 
    |Perform of Action
    |Update of Message

and raise up the action message to the high level

let mainComponent source (model : ISignal<Info>) = 

    let info = Binding.componentToView source "Info" infoComponent model
    //...

    let stat = Binding.createMessage "StatCommand" (Perform Statistic) source
    let input = Binding.createMessage "InputCommand" (Perform Input) source
    //let ...

    [info; stat; input; ...]

let appComponent = 
    let model = initInfo
    let update message model = 
        match message with
        |Update message -> 
            match message with
            |...
        |Perform action -> 
            performAction model action
            model

    Framework.basicApplication model update mainComponent

(Well, I like first option, cause this actions don't change the model)

Is it correct way (the first, obvious) to do these things or library contains more fitting function ?

P.S. I looked for Observable.concat [info; stat; input; ...] but wasn't catch lucky.

like image 830
Ev_Hyper Avatar asked Aug 07 '17 18:08

Ev_Hyper


1 Answers

So either option is fine here. I think the appropriate approach depends on how this is used, and what data is required:

  • If the "Action" is something that should be handled by the component in its entirety, the first option is completely valid. This encapsulates the work of that component within that function for setting up the binding, and keeps it out of the model entirely.

  • If the "Action" requires anything outside of the model (or available piece of the model), propagating upwards like Option 2 makes the most sense. This allows the model to work with the action, and handle it appropriately.

like image 161
Reed Copsey Avatar answered Nov 02 '22 16:11

Reed Copsey