-
Notifications
You must be signed in to change notification settings - Fork 142
Non-DOM events #132
Comments
@neonstalwart was talking about using 'events' instead of 'channels' but im not sure how he did this |
correct - the function associated with a channel can only be triggered from dom-delegator. only dom-delegator has access to the handler store that uses the handle as a key to get the function associated with the handle. if you want something that will be triggered by the DOM and give you the ability to trigger it yourself, use |
function App() {
var state hg.struct({
events: hg.input([ 'checkDemonState' ]),
// ...
});
state.events.checkDemonState(function (thing) {
console.log(thing);
});
return state;
}
var app = App();
hg.app(document.body, app, App.render);
app.events.checkDemonState('hello world'); |
@Raynos thoughts? why did you mark it as deprecated? |
Thanks for everybody! I see one more difference than |
@kuraga function autoWire(state, events, update) {
Object.keys(events).forEach(function (key) {
var respond = update[key];
if (respond) {
events[key](respond.bind(null, state));
}
});
}; you use it like this: var update = {
checkDemonState: function (state, thing) {
console.log(thing);
}
};
function App() {
var state = hg.struct({
events: hg.input([ 'checkDemonState' ]),
// ...
});
autoWire(state, state.events, update);
return state;
}); back to channels though... channels are a way to guarantee that your handler can only be triggered by a DOM event. with that guarantee comes the restriction that your handler can only be triggered by a DOM event 😄 maybe i'm undisciplined but i find it very useful to be able to trigger events without necessarily having a user interaction or be able to translate a DOM event handled on one component to an event that is part of another component. an example of doing something without a DOM event might be a toaster component that shows messages to a user and allows the user to click 'X' to dismiss the message or after a few seconds it closes itself (without a DOM event). in both cases i would want |
Nice hook! Unify channels and input maybe? |
@Raynos
...
|
I don't know if there's much to unify. input is more or less a superset of channel since everything you can do with channels you can do with input except for the guarantee that an event was generated by a DOM event if you use channels. so ultimately it's just your choice of which one you need. |
to put it another way, the things which are different about channel and input is not something which can be unified because the unique part of each one is incompatible with the unique part of the other. |
Because input was never meant to be written to by other components. It's a convenient way to allow siblings to communicate and to allow grandchildren & grandparents to communicate. What I really wanted input to be, is channels, channels are only for DOM events. The reason inputs won't work is because they cannot be serialized, one of the less documented design goals of mercury and mercury applications is to be able to serialize the entire application state into a blob, save it to disk or share the blob with a friend over IM, then load it and be at the correct application state. This means that the event communication system we use between multiple mercury components must be resilient to serialization, either by being statically configured at startup and not being dynamic or being serializable itself. This is an open problem that is not solved yet, I started experimenting with a solution here ( https://github.com/Raynos/mercury/blob/master/examples/todomvc/todo-app.js#L34-L36 ) but it's not proven yet. |
See @neonstalwart answer. They do different things. We need to find something like input but ensure its serializable. Although if you do not care about serialization you can always just use input. |
Thanks to all! |
@Raynos I guess I don't understand how using events violates serializability of state. Are you trying to cut out a class of subtle hidden-state bugs? or what is your thinking there? |
Imagine if you have an empty app. You then serialize a very complex state into the app. You now have a ton of state, but no constructor or factory functions were called. There are functions all over the place that set the event relationships with the Every time you saturate a complex data structure into your app you have to make sure all the event communication listeners and emitters are set up correctly, this is non trivial. |
@Raynos wouldnt setting up the event listeners be a natural product of defining the parts and passing the state through the component hierarchy ? |
maybe i need a more concrete failure case to wrap my head around the aversion |
👍 |
@kumavis think of the todomvc case. It has a list of todos. Each time it creates a todo it pushes it into the list and listens for events on the todo item. It only listens for events when it pushes the todo item into the list. How does it listen for events when the entire list is hydrated with the new state. There are just so many edge cases around dynamic components, lists of child components, hashes of child componenets. |
@Raynos wouldn't it start listening for events as part of the instantiation process of each child element? Let's say each item in the list represents a twitter tweet, and it listens for 'wasStarred' events over the network to update itself. The TweetComponent would setup a new network i/o listener on instantiation. no? |
@kumavis your assuming we create a tweetcomponent. When we hydrate an array we just put data into the array and that's it. At which point do we convert plain data structures into instances of TweetComponent ? |
yeah you're right... we'd need something like
where componentMap handles life cycle of array element - component matching |
@kumavis so instead of doing that I have |
After (start of) using Repeat it: function wire(state, events, update) {
Object.keys(events).forEach(function (key) {
var respond = update[key];
if (respond) {
events[key](respond.bind(null, state));
}
});
}; |
No. |
What's the standard way to respond to events such as websockets or AJAX? Simply go with input for now? Same question for testing - how would you test a channel in a situation without DOM? Or should all tests simply involve a DOM and rendering? |
Can I trigger an event outside of template?
The text was updated successfully, but these errors were encountered: