Comments (19)
Hi, I have tried hot-reloading with browserify, webpack and now amok. http://amokjs.com/
It looks like I am not limited to swapping the render function using amok, for example, I can change the incrementCounter
function without losing state. I am fairly new to this however.
The counter example could be modified like this to force a render when the patch event from amok server happens:
var window = require('global/window');
...
function App() {
var appState = hg.state({
amokState: hg.value(Math.random()),
value: hg.value(0),
channels: {
clicks: incrementCounter
}
});
// Modify state on patch event to trigger render.
window.addEventListener('patch', function() {
appState.amokState.set(Math.random());
});
return appState;
}
from mercury.
Questions:
- How do I do custom event handling? A: use data-foo: function (ev) { }
- How do I do custom rendering? A: use a widget
- How do I do update custom properties? A: use a hook
from mercury.
how does the unwrapping of state objects actually work?
from mercury.
The first of the FAQ is making great progress.
I'll keep this issue open so anyone else can chime in with questions here!
from mercury.
Questions:
- How do you do stuff out of scope for dom props like focus()
- How do you do stuff not well fit for data based things, like set focus once, or do something on dom element entry.
from mercury.
i don't know if this belongs in an FAQ but since you can't use dom-delegator for resize events (because you need to listen to resize events on window
), i made my own event for it
var hg = require('mercury'),
resize = hg.input();
window.addEventListener('resize', resize);
return resize;
from mercury.
- state ownership. How do you organize your state object and how do you decide who has ownership
from mercury.
- arguments vs local state. Compare to react, talk about trade offs.
from mercury.
How to specify multiple event handlers for 'ev-*' properties?
from mercury.
- why dom-delegator doesn't listen to mousemove and touchmove and how you can add it yourself https://github.com/Raynos/dom-delegator/blob/master/docs.mli#L13-L14
from mercury.
What is the correct way to get events from Widgets?
For example, I have a CodeMirrorWidget holding a CodeMirror instance. It does a lot of things, I don't care, but I want to grab its value when it changes, but, as mercury doesn't let me handle the events normally (in fact it does, but then I don't get the observable state to update in my event callback) I don't know how to do it.
Now I'm basically doing it the crude way, passing a normal event callback function to the widget, with the global observable state embedded in it, so I can update the state, but there might be something wrong with this.
from mercury.
Handles created from dom-delegator are done here ( https://github.com/Raynos/dom-delegator/blob/master/dom-delegator.js#L29-L36 ).
If you have a handle and are using h
you can just do
h('div', {
'ev-click': handle
})
If you are using the DOM you can use https://github.com/Raynos/dom-delegator/blob/master/dom-delegator.js#L26
var d = mercury.Delegator();
d.addEventListener(domElem, 'click', handle)
If you want to do custom stuff with the event, i.e. transform the DOM event and pass a plain object back instead of passing on a raw DOM event you can use transformHandle ( https://github.com/Raynos/dom-delegator/blob/master/dom-delegator.js#L38-L45 )
Although I recommend you create a higher order function using BaseEvent (https://github.com/Raynos/value-event/blob/master/key.js#L1-L11)
var d = mercury.Delegator();
var MyEvent = mercury.BaseEvent(function (ev, broadcast) {
broadcast({ value: ev.target.value })
})
d.addEventListener(domElem, 'click', MyEvent(handle))
from mercury.
@fiatjaf do you want to contribute a section to the FAQ documenting this in more detail.
I think your codemirror widget + dom-delegator example would be great to add somewhere :)
from mercury.
Ok, I postponed my work on this for a while, but now that I'm reading again and it doesn't solve my problem. CodeMirror (and many other libraries) doesn't emit DOM events, it has a custom event system and you're supposed to listen to events by calling yourCodeMirrorObject.on("change", handle)
.
As I could understand, however, dom-delegator only proxies DOM events, and I can't bypass dom-delegator (it gets everything in my channels
and turn into dom-delegator fake handles)(also it would not be good to bypass it, as I wouldn't get the state
as the first argument to my handle), so it is impossible to handle my CodeMirror events nicely.
My CodeMirrorWidget, actually: https://github.com/fiatjaf/vendasalva-app/blob/mercury/codemirror/vendasalva-widget.coffee
What I want to do:
state = function () {
return hg.state({
text: "foo",
channels: {
inputTextChanged: function (state, codemirrordata) {
state.text.set(codemirrordata.cm.getValue())
}
}
})
}
(...)
h('div', {},
CodeMirrorWidget({
'ev-click': state.channels.inputTextChanged
})
})
What I'm doing, because I can't find another way:
state = function () {
return hg.state({
text: "foo"
})
}
actualState = state()
standaloneHandlers = (function (state) {
return {
inputTextChanged: function (codemirrordata) {
state.text.set(codemirrordata.cm.getValue())
}
}
})(actualState)
h('div', {},
CodeMirrorWidget({
'ev-click': standaloneHandlers.inputTextChanged
})
})
What I need, in the end, is a way to let my CodeMirrorWidget fire events that dom-delegator will understand.
from mercury.
@fiatjaf you can generate custom DOM events yourself and tell dom-delegator to listen to those events
however, i think your point about events being tied to dom-delegator is a good one - channels cannot be fired apart from DOM interaction. due to this, i exclusively use hg.input
for my events rather than hg.channels
. my code is not much different to your standaloneHandlers
code though so you're essentially doing the same thing. the one difference is that i put those handlers at state.events
so that the render function does not need to reference standaloneHandlers
via a closure. the pattern i use has update
, input
, component state which includes events
, and render
which attaches the events just like you're doing.
the code to bind state
to each of the update
functions can be generalized into a helper something like:
function autoWire(state, events, update) {
Object.keys(events).forEach(function (key) {
var respond = update[key];
if (respond) {
events[key](respond.bind(null, state));
}
});
}
// use it after generating the component state:
autoWire(state, events, update);
from mercury.
@neonstalwart I can see it is essentially the same hacky trick in your example but, wow, your code is much more elegant than mine, I'm astonished. I'll copy that right away. Later on I'll think about generating custom events, but I think I'll be satisfied with your solution in the cited example.
from mercury.
+1 to @ashnur's question: can we trigger multiple channels from an event?
from mercury.
@eightyeight use an array http://jsfiddle.net/ashnur/7vnqs7oz/
from mercury.
That's obvious and intuitive. Thanks! I'll make a PR to add it to the FAQ.
from mercury.
Related Issues (20)
- live component reloading HOT 6
- Mercury not exporting virtual-hyperscript SVG HOT 2
- Immutable props
- question: how to detect if a widget has been unmounted HOT 2
- Communication between child components
- Why static render methods? HOT 3
- Using vdom-to-html doesn't work (returns empty string) HOT 6
- Redux + mercury example? HOT 10
- lock down wiki?
- syntax of h HOT 2
- npm install fails HOT 1
- 14.1.0 break all VNode input rendering HOT 8
- newb question HOT 4
- Docs/Introduction: Simple Cycle example missing
- Synchronize tagged version and comment in mercury.js
- Rendering subitems of different types HOT 4
- What is the right way to pass data to click event handlers? HOT 1
- Get the previous version of state var HOT 3
- Splitting components out to their own render loop? HOT 2
- How to attach state to renderer? HOT 10
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from mercury.