Hi Ray,
Fully agree with your last statement. For me, definitely more Java than 
JavaScript, the whole idea of changing *this* is slightly weird. I get the 
Function.bind(), when you pass a function somewhere, but changing this on 
caller side seems strange to me. 

I don't know how often such mechanism are used in JS libraries. For named 
jQuery example, actually there is also the Event object passed, which has a 
*target* element which is the same as the overridden *this*. So in fact you 
can do the same without having access to *this* from JavaScript. So maybe 
it is not that much problematic as I thought. 

Marcin


On Wednesday, 29 April 2015 10:02:46 UTC+2, Ray Cromwell wrote:
>
>
> 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 <[email protected] 
> <javascript:>> 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 [email protected] 
>> <javascript:>.
>> 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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/google-web-toolkit-contributors/2e5fb470-82bf-4085-ba91-11b34695e029%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to