Thursday, June 2, 2016

Re: JsInterop and default settings in JS structures - how to handle?



On Thursday, June 2, 2016 at 1:15:57 AM UTC+2, Hristo Stoyanov wrote:
Hi all,
This is a pretty common in the JS world, but take a look at this JS library, which as part of its API has settings/options for configuration, where options are done with something with JS structure like:

{
  ...
  isContainer: function (el) { return false; }, 
  moves: function (el, source, handle, sibling) { return true; }, 
}


As you can see the callbacks have defaults that allows JS developers not to bother specifying them. Pretty neat! This is accomplished with code like:

function always () { return true; }
var o = options || {};
if (o.moves === void 0) { o.moves = always; }


Now, when I wrap such options object it in JsInterop:

@JsType(isNative = true, name = "Object", namespace = JsPackage.GLOBAL)
class Options {       
     
               ...
 
    @JsProperty
    public CallbackRet1<Boolean, Object> isContainer;

    @JsProperty
    public CallbackRet4<Boolean, Object, Object, Object, Object> moves;


              /** We need this trivial defaults to be singletons */
    public static final CallbackRet1<Boolean, Object> DEFAULT_IS_CONTAINER = o->false;
    public static final CallbackRet4<Boolean, Object, Object, Object, Object> DEFAULT_MOVES = (o1,o2,o3,o4)->true;

    /** A factory methods to set the defaults. Uh-oh!*/
              @JsOverlay
    final static public Options createDefault() {
       Options o = new Options();
       o.isContainer = DEFAULT_IS_CONTAINER;
       o.moves = DEFAULT_MOVES;
       return o; 
    }
 
}

Do I have to provide defaults for callbacks and other properties?  As you can see my current approach leads to verbose code and the getDeafult() method that I would really like to avoid.
What happens if I leave the properties uninitialized? What will the JS API see with such partially supplied options - undefined or null?  I tried putting @JsOptional on all of these properties, but this annotations in not meant for members.


What is the best strategy to handle such cases with JsInterop?

Also, why is JsInterop  not allowing me to initialize the fields at declaration?

With @JsType(isNative=true), fields simply map to JS properties, and the class constructor simply maps to the JS constructor, so there cannot be initialization code; see https://docs.google.com/document/d/10fmlEYIHcyead_4R1S5wKGs1t2I7Fnp_PaNaa7XTEk0/edit#heading=h.b1boa8c235km
This means that when you "new Options()" in Java, GWT will generate a "new $wnd.Object()" in JS. This in turns means that uninitialized "Java fields" will be left 'undefined' in JS.

(note: I haven't tried it, this is my interpretation reading the "JS interop spec", and what I would expect from GWT)
 

--
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 post to this group, send email to google-web-toolkit@googlegroups.com.
Visit this group at https://groups.google.com/group/google-web-toolkit.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment