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

How to do page jump when clicking a button inside a partial page? #14

Closed
LeonLiuY opened this issue May 4, 2016 · 1 comment
Closed

Comments

@LeonLiuY
Copy link

LeonLiuY commented May 4, 2016

In the example, there are event handlers in the TOC which changes "currentPage" in the model of the root page. This leads to a page jump.

However, inside a partial page, it seems not possible to update the model of the root page. Then how to do a page jump in a partial page.

I have tried 2 ways:

  1. Use <a> tag and specify the href attribute.

    This really works well, but the limitation is that I have to use <a> tags. Sometimes page jump is required on other user events instead of link clicks.

  2. Make an Action in event handlers, and return Effects using History.setHash

    This works, but I found a strange problem that occasionally the page jump will finally return to the current page. (There is a flash)

    I'm not quite sure why this happens. But I guess location2action or delta2update has been triggered multiple times in this scenario. Since the Effects need an Action type stand-by and I have to set it to NoOp and do nothing with it. But will this NoOp action trigger a new delta2update ?

I'm confused with this behavior, and want to ask what is the best way to make page jump in a partial page.

@rgrempel
Copy link
Owner

rgrempel commented May 4, 2016

Yes, I suppose that the NoOp would trigger a new delta2update, since it would push another model through the signal graph. Of course, it's the same model (as you say, you do nothing with it), but I'm not sure we can test for that (in the general case), since we don't know what's in your model, and it might not work with Elm's equality test (which is partial). I suppose that we could ask for a (perhaps optional) equality-testing function in the configuration, and use it if supplied.

Now, your delta2update function is supplied with both the old and new model, so I suppose you could do the testing for equality yourself (if your model is suited to it) and return Nothing if they are the same. It's possible that might help your case.

In any event, if it's happening occasionally, then it sounds like a race condition. There must be two async things happening here, which normally happen in the desired order, but sometimes not. If I recall correctly, History.setHash is implemented inside a setTimeout, so it's async. So, normally you'd expect it to happen after the NoOp is processed. However, sending actions to addresses is also inherently async, so perhaps occasionally the delta2update triggered by the NoOp happens after the History.setHash? It must be something of that kind, at any rate.

Of course, elm-route-hash isn't aware of your explicit use of History.setHash, so it's not straightforward to special-case it.

All that being said, the general philosophy behind elm-route-hash is that ideally you shouldn't go through the hash in order to change your model -- you should just change your model in the ordinary way, and let the hash follow along. (That is, the url handling should sit alongside your normal state transformations, rather than being an essential part of them).

So, ideally the best way to attack your problem would be by figuring out how to deal with this:

However, inside a partial page, it seems not possible to update the model of the root page.

Now this, it seems to me, is an example of the general question of "How does a sub-component trigger a change in a parent's model?" And that, in turn, is a common question of general interest.

In principle, there are only two possible answers:

  • the parent passes something in that the child can use to construct an Effect; or
  • the child returns something the parent can look at.

Which, generally speaking, means modifying the standard signature of the child's update function to either:

  • include an extra parameter (often called "context", being a record of whatever additional things the child needs -- for instance, possibly an Address to send actions to); or
  • include an extra thing in the return type (i.e. something in addition to the model and an Effect), which the parent might consult.

I did a little googling around children updating parent's state in Elm, and got this (amongst other things), which suggests one plausible approach:

https://www.reddit.com/r/elm/comments/3plxaw/child_component_changing_state_on_parent/

Of course, I may have misunderstood your needs, but I think figuring out how to get children to update their parent's state might be helpful in your situation.

@LeonLiuY LeonLiuY changed the title How to do page jump when clicking of a button inside a partial page? How to do page jump when clicking a button inside a partial page? May 5, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants