-
Notifications
You must be signed in to change notification settings - Fork 10k
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
Improve JS-side event handling code #16293
Comments
@SteveSandersonMS I've been looking into creating an EventBroker using Rx.DOM and have a simple working POC where a developer can register an event handler (observer) if the source element event hasn't been registered previously then the EventBroker creates an observable using the fromEvent holding onto the source, which is subscribed to internal EventBroker methods that in turn raises events to the observer that subscribed to the EventBroker events using a filter. |
@grahamehorner @SteveSandersonMS I am looking into how the approach would be for this to replace what is already in Replace the switch statement here with .... if (attributeName.startsWith('on')) {
let callback: EventListener = evt => raiseEvent(evt, browserRendererId, componentId, eventHandlerId);
if (toDomElement['_blazorDeregisterEvent'] && toDomElement['_blazorDeregisterEvent'][attributeName]) {
toDomElement['_blazorDeregisterEvent'][attributeName]();
}
toDomElement['_blazorDeregisterEvent'][attributeName] = () => this.addEventListener(toDomElement, attributeName, callback);
} I want to pull out the non generic event object and move it to new interfaces/classes in order to determine how to construct it so that the C# code on A more robust option might be to provide default event parsing libraries to convert JSON objects to a C# object. For example, convert a MouseEvent (JS) to a UIMouseEvent (C#). This way we can utilize what is already built into JS as to minimize the maintenance on that side. var event = EventJSON.TryParse<UIMouseEvent>(event); This way you can utilize the JS |
@bdparrish I'm starting to come to a similar conclusion around capturing the DOM event raise and serializing the event into a json payload that is then raised to the .NET EventBroker (if required) in essence you have an EventBroker on each side that has a strong contract passing the events via the interop layer. I was initially looking at RxJs DOM and Rx.NET as the core for the EventBroker and have a POC working; but I'm a noob with the client side scripting stuff |
The RxJS works like a Pub/Sub pattern from everything that I have used it for. You would still need to rewrite the |
@bdparrish not sure what you driving at here? Rx/RxJs is an observer pattern on streams of data; UI events are simply streams of data; all the addEventListener/removeEventListener logic would be handled by the using Rx.Observable.fromEvent
the resulting observable (source) can be subscribe to by one or more observers; the scoping of the observable would be controlled by the EventBroker with a signal observer bound to the events of observables; and filtered/dispatched to EventBroker registered handlers using promise/async calls |
RxJs can also be used to throttle events/aggregate etc. should it be needed to prevent performance issues with interop calls aka backpressure |
I am saying Pub/Sub, but synonymous with Observable in my mind, hence the I still think the below is a more sensible approach so that Blazor can fluctuate easily with JS changes in the future to take the event that JavaScript already builds for you and then send that over to C# to process. platform.callMethod(raiseEventMethod, null, [
platform.toDotNetString(JSON.stringify(eventDescriptor)),
platform.toDotNetString(JSON.stringify(event))
]); and then (there is a way better way to do this but getting thought on "paper") ... private static UIEventArgs ParseEventArgsJson(string event)
{
if (JsonUtil.TryParse<UIMouseEventArgs>(event, out var mouseEvent))
{
return mouseEvent;
}
else if (JsonUtil.TryParse<UIKeyboardEentArgs>(event, out var keyboardEvent))
{
return keyboardEvent;
}
... etc ...
} This approach limits the JS code and lets the Blazor system handle it the way it wants to and you still get known data. |
Please consider adding WheelEvent to allow triggering of .net code from js when the mouse wheel is used to scroll, eg. scrolling could be used to preload/process data from a service which updates the DOM elements |
Please consider adding the ability to handle BOM window events. An example use case would be in creating a custom install dialog for a Blazor PWA by leveraging the "beforeinstallprompt' event.
|
@ChrisMyrick Could you please open an issue for this request on https://github.com/aspnet/aspnetcore/issues? That's where all the Blazor work happening now. |
@danroth27 - Yes, thank you. Done. |
Currently the event handler registration logic in
BrowserRenderer.ts
is not very good. It only supports having a single event handler per element for a given event name, and it doesn't use event delegation, so it's creating new native handlers for every element that responds to events. Also it's hard-coded to only work withonclick
,onchange
, andonkeypress
. It was just put in quickly with the intention of being replaced.We should replace this with a simple event delegation system, and add tests to show that it copes with (for example) both
bind
andonchange
on the same element, plus even custom event names.The text was updated successfully, but these errors were encountered: