Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Elmish] Button.onClick handlers not getting updated by view #379

Open
MaxWilson opened this issue Dec 17, 2023 · 4 comments
Open

[Elmish] Button.onClick handlers not getting updated by view #379

MaxWilson opened this issue Dec 17, 2023 · 4 comments
Labels
enhancement New feature or request good first issue Good for newcomers

Comments

@MaxWilson
Copy link

A button, once created, will update its content in response to a new view, but will not update its onClick. This leads to buttons that say they'll do one thing actually doing another.

Repro:
1.) Clone https://github.com/MaxWilson/AvaloniaRepro
2.) Dotnet run
3.) In the app, click on "Add Ryan" and then "Say something Ryan"

Expected: it should say "Ryan: Blahblahblah".
Actual: "Bob: Blahblahblah".

type Model = {
    people: string list
    chatLog: string list
    }
type Msg =
    | Speak of person:string * msg: string
    | NewPerson of name:string

let init _ = {
    people = ["Bob"]
    chatLog = []
    }

let update msg model =
    match msg with
    | Speak (person, msg) ->
        { model with chatLog = (sprintf "%s: %s" person msg) :: model.chatLog }
    | NewPerson name ->
        { model with people = name :: model.people }

let view model dispatch =
    StackPanel.create [
        StackPanel.children [
            for person in model.people do
                Button.create [Button.content $"Say something {person}"; Button.onClick (fun _ -> dispatch (Speak (person, "Blahblahblah")))]
            for msg in model.chatLog do
                TextBlock.create [TextBlock.text msg]
            if model.people.Length = 1 then
                Button.create [Button.content "Add Ryan"; Button.onClick (fun _ -> dispatch (NewPerson "Ryan"))]
            if model.people.Length = 2 then
                Button.create [Button.content "Add Sarah"; Button.onClick (fun _ -> dispatch (NewPerson "Sarah"))]
            ]
        ]
@MaxWilson
Copy link
Author

Based on #369 it looks like the fix is to always specify SubPatchOptions.Always with OnClick.

type Button with
    static member onClick logic =
        Button.onClick(logic, SubPatchOptions.Always)

@MaxWilson
Copy link
Author

Is there a reason why Always isn't already the default?

MaxWilson added a commit to MaxWilson/Mandrake that referenced this issue Dec 17, 2023
@JaggerJo
Copy link
Member

JaggerJo commented Dec 18, 2023

Good question.

In earlier versions of funcUI elmish was the only programming model. With elmish you end up having one gigantic view tree that you need to diff + patch on every update. In this scenario not patching the click property of 100s of buttons on every updates was a valid argument.

Now for the component model.. I'm not so sure.

@JaggerJo
Copy link
Member

@MaxWilson we could make the default configurable.

@JaggerJo JaggerJo added enhancement New feature or request good first issue Good for newcomers labels Feb 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

2 participants