Monday, August 31, 2020

Re: CustomEvent examples

On 28. 08. 2020. 23:28, Thomas Broyer wrote:
>
> https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events
>
> The second example would be coded as:
>
> CustomEventInit<Double>eventInit =CustomEventInit.create();
> eventInit.setDetail(time);
> CustomEventevent=newCustomEvent("build",eventInit);

With the exception of CustomEventInit not being generic, this code works,
thanks Thomas.

In an example of event to signal that particular user is saved, this is what
I got working:

Declarations:

public static final String SavedEventType = "saved";

Init:

addEventListener(SavedEventType, this::onSaved);

Dispatch:

public void save(User user) {
CustomEventInit eventInit = CustomEventInit.create();
eventInit.setDetail(user);
eventInit.setBubbles(false);
CustomEvent event = new CustomEvent(SavedEventType, eventInit);
dispatchEvent(event);
}

Listener:

public void onSaved(Event event) {
CustomEvent customEvent = (CustomEvent) event;
User user = (User) customEvent.detail;
Log.info("User is " + user.getId());
}

Looks very fragile, especially if I decide to use complex details in which
case I'll have to expose internal structure of that field.

IMHO, best solution would be to extend CustomEvent, but I didn't find a way
to do so (as least not in a way to be able to *receive* instances of that
descended class, not even using Js.uncheckedCast, which, to my understanding
of JsInterop, is not even possible), so this is best I got:

public class SavedEvent {

public static final String Type = SavedEvent.class.getName();

@JsType(isNative = true, name = "CustomEventInit", namespace =
JsPackage.GLOBAL)
public static interface Init extends CustomEventInit {

@JsOverlay
static SavedEvent.Init create() {
SavedEvent.Init init = Js.uncheckedCast(CustomEventInit.create());
init.setBubbles(false);
return init;
}

@JsOverlay
default User getUser() {
return (User) getDetail();
}

@JsOverlay
default SavedEvent.Init setUser(User user) {
setDetail(user);
return this;
}

@JsOverlay
default CustomEvent event() {
return new CustomEvent(SavedEvent.Type, this);
}

}

public interface Listener extends EventListener {
default void handleEvent(Event event) {
handleEvent(new SavedEvent(event));
}
void handleEvent(SavedEvent event);
}

public SavedEvent(Event nativeEvent) {

// add at least some safety...
if (!(nativeEvent instanceof CustomEvent) || !Type.equals(nativeEvent.type))
throw new IllegalArgumentException();

this.nativeEvent = (CustomEvent) nativeEvent;

}

public CustomEvent getNativeEvent() {
return nativeEvent;
}

public User getUser() {
return (User) nativeEvent.detail;
}

private final CustomEvent nativeEvent;

}

Which contains a lot of boilerplate wrappers, but at least now dispatchers
and listeners (which are exposed to users) looks more decent:

addEventListener(SavedEvent.Type, this::onSaved);

public void save(User user) {
dispatchEvent(SavedEvent.Init.create().setUser(user).event());
}

public void onSaved(SavedEvent event) {
Log.info("Saved user is " + event.getUser().getId());
}

Any suggestions for further simplifications when working with specialized
events?

-gkresic.

--
You received this message because you are subscribed to the Google Groups "GWT Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit/20399da1-6fbe-d6a0-2514-26414a8e40a8%40steatoda.com.

No comments:

Post a Comment