In Elmish.WPF, can submodels be run asynchronously or in parallel?

77 Views Asked by At

I apologize upfront for all the code following this question. Its included to answer any questions -- I hope.

In Elmish.WPF, I have submodels of submodels of submodels. Each submodel is esentially a list.

That is, I have a main DataGrid, an "AppointmentTable", bound to a Rows list. Each Row has a column list; Each column has a cell list. Lastly each cell is bound to a name.

Updating each of these models takes more time then I am willing to wait. I have two questions; I a mostly interested in the concepts involved:

  1. Can each submodel use Cmd.OfAsync.either where only ONE delay is made when ALL the models are updated and screen updated, and
  2. Would there be any way of running all submodels asynchrounously in parrellel?

TIA

WPF:

 <!--DataContext is MainWindow.fs-->          
            <TabControl ...>
                <TabItem Header="Appointments">
                    <Grid DataContext="{Binding Appointments}">                    
                        <local:Appointments Grid.Column="2" Grid.Row="0" />
                    </Grid>
                </TabItem>
                
                
    

 <!--DataContext from MainWindow ="{Binding Appointments}"-->
    
            <DataGrid Grid.Row="1" x:Name = "AppointmentTable" ItemsSource="{Binding Rows}" ...>
                <DataGrid.Columns>
                    
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <Grid DataContext="{Binding Columns[0]}">
                                    <ListView ItemsSource="{Binding InnerRows}" 
                                      
                                        <ListView.View>
                                            <GridView>
                                                <GridViewColumn Header="First"   Width="100">
                                                    <GridViewColumn.CellTemplate>
                                                        <DataTemplate>
                                                            <TextBlock Text="{Binding Path=FirstName}"/>
                                                            
                                                        </DataTemplate>
                                                    </GridViewColumn.CellTemplate>
                                                </GridViewColumn>

                                                <GridViewColumn Header="Last"  Width="120">
                                                    <GridViewColumn.CellTemplate>
                                                        <DataTemplate>
                                                            <TextBlock Text="{Binding Path=LastName}"/>
                                                            
                                                        </DataTemplate>
                                                    </GridViewColumn.CellTemplate>
                                                </GridViewColumn>

                                                <GridViewColumn Header="Bd" Width="80">
                                                    <GridViewColumn.CellTemplate>
                                                        <DataTemplate>
                                                            <TextBlock Text="{Binding Path=BirthDate}"/>
                                                            
                                                        </DataTemplate>
                                                    </GridViewColumn.CellTemplate>
                                                </GridViewColumn>
                                            </GridView>
                                        </ListView.View>
                                    </ListView>
                                </Grid>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
    ----------------------------------------------------------------------------------------------------

F#

module Mainwindow
       type Model =
        { Appointments: Appointments.Model
          ......
        }
   
       // DataContext for Appointments.xaml
    "Appointments" 
        |> Binding.SubModel.required Appointments.bindings
        |> Binding.mapModel (fun m -> m.Appointments)
        |> Binding.mapMsg AppointmentsMsg
        

module Appointments
        type Model =
           { Rows: Row.Model list
             
            }

   "Rows" |> Binding.subModelSeq(
     (fun m -> m.Rows),
     (fun (m, outerRowModel) -> (m.SelectedOuterRow = Some outerRowModel.Id, outerRowModel)),
     (fun (_, outerRowModel) -> outerRowModel.Id),
     RowMsg,
     Row.bindings)                  

module Row =
        type Model =
          { Columns: Column.Model list 
            ...}
            
    "Columns" |> Binding.subModelSeq(
                (fun (_, outerRowModel) -> outerRowModel.Columns),  
                (fun ((b, outerRowModel), columnModel) -> (b && outerRowModel.SelectedColumn = Some columnModel.ColumnId, columnModel)),  
                (fun (_, columnModel) -> columnModel.ColumnId),    
                ColumnMsg,                                   
                Column.bindings)                                

module Column =
       type Model =
        {  Cells: Cell.Model list
          ....
        }
        
    "InnerRows" |> Binding.subModelSeq(
    (fun (_, m) -> m.Cells),
    (fun ((_, m), cellmodel) -> (m.SelectedCellId = Some cellmodel.Id, cellmodel) ),
    (fun (_, cellmodel) -> cellmodel.Id),
    snd,
    Cell.bindings)  
        

module Cell =
        type Model =
            { Id: int
              AppointmentTime: DateTime
              Appointment: Visit option }

      let bindings() = [
        "LastName"  |> Binding.oneWay(fun (_, c) -> 
                                        match c.Appointment with
                                        | Some a -> a.LastName
                                        | None -> ""
                                     )
        "FirstName" |> Binding.oneWay(fun (_, c) -> 
                                        match c.Appointment with
                                        | Some a -> a.FirstName
                                        | None -> ""
                                     )
        "BirthDate" |> Binding.oneWay(fun (_, c) -> 
                                        match c.Appointment with
                                        | Some a -> a.BirthDate.ToShortDateString()
                                        | None -> ""
                                     )
        "ServiceTime" |> Binding.oneWay(fun (_,c) ->
                                          match c.Appointment with
                                          | Some a -> a.EncounterTime
                                          | None -> None
                                       )
        "SelectedLabel" |> Binding.oneWay (fun (b, _) -> if b then " - Selected" else "")
    

]

0

There are 0 best solutions below