fsbolero / Template

dotnet cli template to create Bolero applications

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Question: Better way to handle linq expression for Blazor component?

fwaris opened this issue · comments

Working with AntDesign Table.... In Blazor a table can be defined as:

<Table @ref="table"
       TItem="Ak"
       DataSource="@forecasts"
>
  <Selection Key="@(context.Id.ToString())" />
  <PropertyColumn Property="c=>c.Id" />
</Table>

In Bolero, the following seems to work but wondering if there is an better way:

open System.Linq.Expressions
open FSharp.Linq.RuntimeHelpers

let (idExpr:Expression<Func<Ak,int>>) = LeafExpressionConverter.QuotationToLambdaExpression <@ Func<Ak,int>(fun (o:Ak) -> o.Id) @>

let alarmGrid (alarms:Ak[]) : Node  =    
    comp<Table<Ak>> { 
        "DataSource" => ResizeArray(alarms) 
        "PageSize" => 25
        
        attr.fragmentWith "ChildContent" <| fun (context: Ak) ->
            concat {
                comp<Selection> {"Key" => "@(context.Id.ToString()"}
                comp<PropertyColumn<Ak,int>> {
                    "Property" => idExpr
                }
            }
    }

Setting the value of 'Property' on 'PropertyColumn' requires an explicit conversion to a Linq Expression. I would have preferred to use a simple lambda, as in:

comp<PropertColumn<Ak,int>> {
   "Property" => (fun (o:Ak) -> o.Id)
}

But the above gives me a cast expression error at runtime.

F# is capable of compiling a lambda as a LINQ Expression, but only when passed to a class method. So I think something like the following should work:

type Attr =
    static member Property(expr: Expression<Func<Ak, int>>) =
        "Property" => expr

// ...
comp<PropertyColumn<Ak, int>> {
    Attr.Property(fun o -> o.Id)
}

Closing as answered.