Skip to content

hotreload hook #3227

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

Closed
wants to merge 1 commit into from
Closed

hotreload hook #3227

wants to merge 1 commit into from

Conversation

vird
Copy link

@vird vird commented Jul 5, 2016

No description provided.

@yyx990803
Copy link
Member

What's the use case for this? A normal component should not be concerned with how it's hot-reloaded.

@vird
Copy link
Author

vird commented Jul 5, 2016

I have some complex component with many subcomponents. I need hidden textarea for input capturing. I create root component with textarea. I need clicks on any subcomponent lead to focus on this textarea. I don't want seek local root component with $parent walking and seeking for magic property.
So I create single object (shared controller) with focus method. So I handle all clicks with some action and maintain focus on textarea.
Now hotreload comes. It triggers rerender of root component and after that replaces state with old one. old state includes old textarea reference.

@yyx990803
Copy link
Member

I think the problem is that you are placing the textarea reference in your component state. Component state should be pure serializable data. The textarea reference doesn't need to be in the state. You can just attach it to the instance in the ready hook with this.sharedController = ....

@yyx990803 yyx990803 closed this Jul 5, 2016
@vird
Copy link
Author

vird commented Jul 5, 2016

You can just attach it to the instance in the ready hook with this.sharedController = ....
No, I can't, because after 'ready' method comes state replace from hotreload.

@yyx990803
Copy link
Member

Do not define sharedController inside data at all, then it won't be replaced. It's just a normal property on the Vue instance.

@vird
Copy link
Author

vird commented Jul 5, 2016

I have complex app with multiple editors. I don't know exact count of components. I can bootstrap Vuejs as separate app, but it breaks idea of vuejs components, because now it's two types of components: native vuejs and bootstraping with sharedController provided in props.

@yyx990803
Copy link
Member

I don't think I understand your last comment and how it relates to the solution I suggested. But to be concise, your sharedController doesn't need to be defined in data. Just do:

created () {
  this.sharedController = sharedController
}

If this doesn't work due to other constraints, then you didn't provide enough context. Either way, this should not be solved by adding a hotreload hook.

@vird
Copy link
Author

vird commented Jul 5, 2016

Ok. Let's make it simplier.
sharedController is just mediator. It recieves 'focus' messages from all complex component. I need make actual textarea focused when 'focus' event occur.
What happens when I init app.
I need somehow told sharedController what to do on 'focus' event. So I provide closure with actual reference to textarea. All works ok.
Hotreload comes.
New component tree created with new sharedController. All is ok: new tree with new sharedController, old with old one. Ready hook comes. I told new sharedController what to do on 'focus' event.
Now hotreload replaces all my state in new component with old sharedController. How old sharedController (from previous state) should be updated? There are no events after hotreload updates state.

@yyx990803
Copy link
Member

Did you understand my suggestion? sharedController is not part of the state if you avoid declaring it in data.

@vird
Copy link
Author

vird commented Jul 5, 2016

Hm. It works, but it's kind'a injecting in component. I can accidently replace some important property. I suggested that there is only several safe spaces for state: data, props.

@vird
Copy link
Author

vird commented Jul 6, 2016

I tested some time solution with 'created' method. I've found that it works only in this simple case, that I mentioned above.
I have another case, when hotreload hook is much simpler.
I have some two types of components

  1. Complex structure DOM-based component with one hidden textarea that capture all keyboard activity
  2. Simple canvas-based component with hidden textarea.
    I have component for multiple keyboard scheme handling. Problem 1. Current scheme is a state. After hot reload I will be switched to default scheme.
    Ok. I extend keyboard_controller for different components with actions specific to that component. Actions could be result of keyboard actions or mouse actions.
    So I want handle all mouse events with that controller. Problem 2. Canvas must be pannable, so I must store offset_x, offset_y between hot reloads.

So, I have two solutions:

  1. Without hotreload hook. I must make state detachable from controller, because state must preserve with hot reload. After 'ready' I must setTimeout for waiting hotreload applies. Now data has old state, I can attach this state to controller and call update, that would redraw all canvas contents to actual state (not clean canvas, but with elements, pan, other state before hotreload)
  2. With hotreload hook. Just update textarea, canvas reference. Then call update.

Pros:

  1. If error occurs in hotreload hook, page would be reloaded, due hotreload exception catch logic, not my custom.
  2. setTimeout/setImmediate not guarantee that no changes occur between 'ready' and after hotreload, so external data feed can easily break the state. Hotreload hook is sync.
  3. I can organize code as I want, framework not limits me.
  4. (almost impossible case) It's stable if hotreload would be async and setTimeout would be fired before state replace.

Cons:

  1. If controller initialization is long, I want no new controller created at all, so I want fully different path of hooks for hotreload and typical create. It's too much changes and can be fragile.

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

Successfully merging this pull request may close these issues.

2 participants