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

For input elements, change event callback happens before data model is updated? #668

Open
AmaiKinono opened this issue Sep 8, 2024 · 4 comments
Labels
data binding enhancement New feature or request

Comments

@AmaiKinono
Copy link
Contributor

I've created an example in the tutorial directory. Here are the important bits:

index.rml:

<rml>
<head>
    <link type="text/css" href="index.rcss"/>
    <title>Window</title>
</head>
<body data-model="data">
    <input type="text" data-value="text" data-event-change="print_self"></input>
</body>
</rml>

main.cpp:

// ...
#include <iostream>

Rml::String text;

void print_text(Rml::DataModelHandle, Rml::Event&, const Rml::VariantList&)
{
  std::cout << text << "\n";
}

bool SetupDataBinding(Rml::Context* context, Rml::DataModelHandle& model)
{
  Rml::DataModelConstructor ctor = context->CreateDataModel("data");
  if (!ctor) {
    return false;
  }
  model = ctor.GetModelHandle();
  ctor.Bind("text", &text);
  ctor.BindEventCallback("print_self", &print_text);
  return true;
}

// ... in main function

    Rml::Debugger::Initialise(context);
    Shell::LoadFonts();

    Rml::DataModelHandle model_handle;
    SetupDataBinding(context, model_handle);

// ...

If we run this in a terminal:

  • Type "a", the terminal prints a blank line.
  • Type "b", the terminal prints "a".
  • Type "c", the terminal prints "ab".
  • If I add a button that calls "print_self", the complete text can be printed.

The same is tested on select element and the behavior is similar.

So it seems the callback is called before data model is updated. What should I do if I need the updated data in such callback?

Thanks!

@mikke89
Copy link
Owner

mikke89 commented Sep 8, 2024

Right, so both of these data controllers effectively add an event listener for the change event. I believe in whichever order they are declared, or actually it might be a bit arbitrary due to unordered maps being involved. And then they just do their thing in that order when the change event is emitted.

For the data views, we are being a lot more comprehensive to give everything a defined update order. However, I believe we don't really do anything like this for the data controllers (value and event). For controllers, I guess it makes more sense to define an initialization order, rather than an update order.

So yeah, I think it makes sense to always initialize the value controller first, so that it gets to the event first. At least I can't really think of any downsides.

@AmaiKinono
Copy link
Contributor Author

Thanks for the explanation. I'd like to talk a bit about the background. I'm trying to complete the 7 GUIs challenge using RmlUi, and the following use cases requires to update the value first:

  • In "Temperature Converter", "Flight Booker" and "CRUD", the application state needs to be updated upon every keystroke in a text input. I think the "update search result while typing" in the "CRUD" example is quite typical.
  • In "Timer" and "Circle Drawer", the state needs to be updated while dragging a slider.

And I didn't found a use case that requires to update the value after a data-event-x callback in this challenge.

@mikke89
Copy link
Owner

mikke89 commented Sep 11, 2024

Oh, interesting. Haven't come across this project before. Definitely some interesting challenges.

I am fully on board with making this change, the use cases here are convincing to me.

@mikke89
Copy link
Owner

mikke89 commented Oct 19, 2024

For reference, here's an old comment describing essentially the same issue, and also a note that data-checked does the expected thing as opposed to data-value (but we should still make the order specified in all of these cases): #482 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
data binding enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants