-
Notifications
You must be signed in to change notification settings - Fork 26
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
Describe a proposed way to do inter-component communication #82
Comments
Had to read twice, but I get what you mean. I do get that this is more a "meteor" way and it surely has it's elegance in it. I'm worried about two things. 1) Performance and 2) Needing a fixed structure.
Cheers! |
I would say that Tracker is probably even better because it is in fact "debounce" on every event. So if you see event as dependency invalidation, if there are multiple invalidations before flush cycle happens, then they are combined into one computation. So with Tracker you can have much more predictable running. If you have only events and you are responding to all events, you might get overwhelmed by them. Also, invalidating a dependency is just switching one flag in the dependency. I am not sure if you can do much better than that. So, my intuition is that it is OK or even better. So please who some numbers. :-)
It is the same as saying that when I dispatch an event with some name, I expect that there is a listener for that event with that name. You expect that, yes? So you can do the same here. You for example search ancestors for a reactive field with a name, and if it is there, you use it, otherwise you do not. In some way it is even better. Imagine that you have a component which has a listener for an even and expects to get those events. But you put a component into a context where nobody will be sending those events. Do you want an error then? So my proposed approach can then support both:
|
I was curious about the price difference between computation and events, so in case it's interesting it's over here http://meteorpad.com/pad/mJnAHp3HGJZJQTKmZ. You'll need to look at your console log to view some sort of numbers. Take note, It appeared hard to get a good honest test :) So hope I did it fair enough. Also, I couldn't fabricate a right way to test a bigger count (loop) while keeping the timing measurements. So although in this example the event approach is faster, once you'll do something that fires say 1000 changes at once, it will differ (as you already said in your debounce point). For me the bottom line was, that the performance point I had earlier is not a real life issue (for me). So although the computation syntax is totally new to me, it's a great solution. |
Wav, thanks! So cool! Thanks for doing it! But I think there is an issue with your measurements. Because the Tracker is computed only at flush intervals. So it is not really comparable to measure something which triggers response immediately, and something which operates on regular interval. Also, you are using DOM events. I thought the second option is to have your own events on top of components tree. Because with DOM events you have another issue: you can send them only in one direction along the DOM tree. You cannot send an event from parent component to all descendant components (without yourself traversing them and delivering an event yourself). |
Np. The current "test" (non-scientific) is as much as possible a representation for the real world current situation. So yes, the tracker will only fire once and only after invaldiation. That's why it will become as fast as events (not faster btw! which I expected it would) in a situation where the events kan be debounced. But that's it's pro, so I wanted to check what it would mean in practice. The same goes for DOM events. That's currently the only way (I know of) to do it, without making adjustments and going around the DOM. So here goes the same as with the tracker, it can be tweaked/adjusted/built upon to make it better/faster/easier, but for now this'll work. Only for this simple test thing. About the order of events. Although in my experience, you'll need the "bubble" (upward) phase of the event in 99,99% of the cases, it does also go downward (although limited to UI composition, you click what is visible and it will only go down to the deepest UI object you click) in the "capture" phase. So if it would be a must have, that might be an option. This is btw the one thing that makes events a nice solution in my case. You can create truly decoupled components with their own API. A component just has it's methods an it's events. That's it. What the outside world want's to do with that API in each specific context, is their call. But as you said, that is indeed also doable with the tracker based solution. And that might be fine as well. I'm old-school, so for me the events made more sense (but not the golden egg) :) |
Context: meteor/meteor#4909 (comment) reactive-field looks great :-), will try that!
Well it is not actually global. Each component has the same structure, it's recursive. The interpreter hosts a rooting table: => each component can be developped independently from the context, because it The topology is not included in the network of templates but rather in the rooting tables, else it makes the components to rely on an implicit context that has to be discovered by "looking up" in ancestors: it tieds them together when I'm searching for a way to split the development in parallel and merge it afterwards. Merging <=> building a routing table + interpretation of messages. let's say that tpt4 requires some data Instead of having to rely on a chain of templates where to look up for:
if tpt1 hosts a rooting table and binded tpt4 then we only have:
We "hope over" the other templates. This hope may be quite long in deeply nested app templates... I'm still not finished with the Actor Model but it looks like a great way to get inspiration from... Alan Kay also! |
Interesting. I suggest that you build this on top of Blaze Components. So they can provide you core functionality of components and then you can build on top your communication style. That would be great to have then various packages for various communication styles. (So just a different base class.) Like event-driven, reactive-variables approach I like, the one you are proposing here, etc. |
So describe why event driven communication in other frameworks is just a special case of communication based on reactive methods on components. So for Blaze Components, the proposed way (but not enforced) is to navigate the component tree and find your component and then call public methods on that component (possibly reactive). This allows much more complex interactions. For example, try to create some action when two events happen (mousedown and mousemove). You have to store local state for one event to know when to do something with another. When you have reactive source you can simply do things like:
And if you want just normal event handling (so wait for only event and then do something and never again), you can use this pattern:
Because I think the first use case is more common than the second (you more often want some declarative reaction to multiple state changes) and second one can also be done, I find this pattern more powerful. Also, you do not have any issues with event propagation and event going too far and so on. Here you explicitly find the component and attach to that reactive source.
Maybe provide some helper functions for this as well?
The text was updated successfully, but these errors were encountered: