seed-rs / seed

A Rust framework for creating web apps
MIT License
3.81k stars 155 forks source link

Question about nested components #604

Closed mcscholtz closed 3 years ago

mcscholtz commented 3 years ago

Thanks for the wonderful framework I have really been enjoying using it.

I have run into a bit of a snag that I was hoping someone can point me in the right direction.

I have been trying to use nested components but having some trouble. I can change the state (Model) of the sub-components but the DOM does not seem to update even though the model of these sub-components have changed.

Using debug logs I can see the state change but the page layout does not change. In my case I am trying to change an image and it's color. I will see if I can include a minimal example of reproducing this.

MartinKavik commented 3 years ago

Please include that example, I'm not sure we can move forward without it.

mcscholtz commented 3 years ago

I made a repo here: https://github.com/mcscholtz/example

Basically I am trying to do input validation and if the name entered does not match "bob" there should be a red cross on the right (this part works), and a green check mark if it does (does not work). I can see the events trigger when the condition is correct but the page does not seem to update to reflect the new state.

I'm pretty new rust an web dev in general so I'm sure there is something simple I am missing. Thanks for the help!

MartinKavik commented 3 years ago

I will see if I can include a minimal example of reproducing this.

Please provide a minimal example. Ideally we should be able to replace the lib.rs in the counter example with your example code and run in without problems. If you can't make it simpler, then please write super simple instructions how we can run the example and it has to be cross-platform and ideally without other non-Rust dependencies like Postgre, Python, etc.

glennsl commented 3 years ago

Just looking at the code, the implementation of the input component looks a bit sketchy.

First of all because it's violating the basic premise of Elm-like architecture/declarative UIs, that the view should be a pure function of the model. Instead it keeps the state in the DOM, which means it'll be lost if the input element is removed and re-inserted, which it could be for a number of reasons.

Secondly, you're putting functions in the model, which is bad because you can't print, compare or inspect functions, and that makes debugging and optimization much harder. It's also very easy for a function to close over a variable and assume it'll change over time because you mutate it elsewhere.

You should instead store the value in the model, getting it from input_ev(Ev::Input, ...) and setting it using At::Value. I would also pass the validation configuration in the view instead of storing it in the model. In general you should not put static configuration in the model, and to the extent you need it to be dynamic you should still only put data in the model, and then configure it it in the view, passing functions and what-not, based on that data.

I'm not sure any of these issues are the cause of your problem though, but they're definitely suspicious and also makes it significantly harder to reason about the code.

mcscholtz commented 3 years ago

I will see if I can include a minimal example of reproducing this.

Please provide a minimal example. Ideally we should be able to replace the lib.rs in the counter example with your example code and run in without problems. If you can't make it simpler, then please write super simple instructions how we can run the example and it has to be cross-platform and ideally without other non-Rust dependencies like Postgre, Python, etc.

Sorry about this, I think the problem is likely how I designed the code as pointed out by @glennsl

Thanks for pointing out some of the flaws, it helps a lot. I will take a look at this and redesign it in a better way. If I still encounter the problem I will create another issue with a minimal example as described by @MartinKavik