Lambda's are inner classes, so there is always a 'this' bound to the
generated instance, otherwise, the handling method wouldn't be invokable.
Imagine if you were implementing this with JSNI:

class HandlerWithThisImpl implements HandlerWithThis {
   public void onEvent(Element target, Event e) { ... }
}

You'd have to write a wrapper that did this:

static native JavaScriptObject makeFunction(HandlerWithThis impl) /*-{
    return function(e) { impl.@onEvent(*)(this, e); }
}-*/;

But to make referential integrity work so that a HandlerWithThis passing
into JS and back into Java always converts to the same function and object
reference, you'd have to generate a lot more boilerplate.


Instead, to make @JsThis work efficiently, you'd have to do something like
this with the magic makeLambdaFunction

/**
 * Create a function that applies the specified samMethod on itself,
and whose __proto__ points to
 * <code>instance</code>.
 */
public static native JavaScriptObject
makeLambdaFunction(JavaScriptObject samMethod,
    JavaScriptObject instance, int jsThisArgPosition) /*-{
  var lambda = function() {
    var args = arguments;
    if (jsThisArgPosition >= 0) {
      args.splice(jsThisArgPosition, 0, this);
    }
    return samMethod.apply(lambda, args);
  }
  lambda.__proto__ = instance;
  return lambda;
}-*/;

It's feasible, but I think the community needs to chime in.  IIRC, the DOM
APIs have changed over the years to include the context as a field of the
event argument.

But perhaps when you look at libraries like Ember, Angular, React,
Backbone, et al, all common is it for the 'this' to be bound, passing this
explicitly as a parameter?

Typical Google coding style internally is if you want to use this, you use
Function.bind() to set it to what you want when you pass in a handler
function to something.

Rebinding this from the calling context seems iffy and dangerous when you
think about Java code.




On Wed, Apr 29, 2015 at 12:32 AM, Marcin Okraszewski <okr...@gmail.com>
wrote:

>
>>>    1. @JsFunction exported to JS doesn't have apply() and call()
>>>     operations. Apply() is used by JQuery (2.1.3) to call callbacks, so
>>>    basically it wasn't possible to add handlers using JQuery. See other 
>>> thread
>>>    on this:
>>>    https://groups.google.com/forum/#!topic/google-web-toolkit/PHtfLTSAJDM
>>>
>>>
>>> Pretty interesting how to model that JQuery callback with JsInterop.
>> Basically when you do $("p").click(handler) then JQuery sets "this" for the
>> handler to the element the event occurred on so you can do
>>
>> $("p").click(function() {
>>    $(this).slideUp(); // slides the clicked p element up
>> });
>>
>> I think you can't really do that with just JsInterop. I think your Java
>> callback must be JQueryCallback.exec(Element elem, Event e) and you have to
>> use JSNI to create a pure JS function that passes "this" as "elem" to the
>> JQueryCallback.
>>
>
>
> This is definitely problematic. I didn't give it too much though, but I
> think it would be great if we could opt-in to get the *this* from
> JavaScript. Something like this:
>
> @JsFunction
> public interface HandlerWithThis {
>    public void onEvent(*@JsThis* Element target, Event e);
> }
>
> If you need the JavaScript *this,* then you just add it as parameter to
> method with @JsThis annotation. As currently @JsFunction is not a
> JavaScript function, but an object that pretend the function, it should be
> possible to implement apply() and call() in such a way, that it passes this
> if there is a @JsThis parameter in the method signature. In case you don't
> need *this*, you just don't specify such parameter; in such case the
> method signature would be void onEvent(Event e). This would be much nicer
> then telling, you need to go to JSNI to do that.
>
> Do you think it could be done like this?
>
> Thanks,
> Marcin
>
>
>  --
> You received this message because you are subscribed to the Google Groups
> "GWT Contributors" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to google-web-toolkit-contributors+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/google-web-toolkit-contributors/97624985-35bf-48d6-b187-76181d9b8672%40googlegroups.com
> <https://groups.google.com/d/msgid/google-web-toolkit-contributors/97624985-35bf-48d6-b187-76181d9b8672%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups "GWT 
Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to google-web-toolkit-contributors+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/google-web-toolkit-contributors/CAPVRV7e-HtaWNMSHWUQM8zkeGS1Ncz1hKaJiFr4_Occ4kArNFw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to