GWT Overlay deep copy

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-06 09:29:39

There are 2 ways that I would consider. Most of the time overlay objects are used in conjunction with JSON, so you could just stringify the object and parse the results:

public native MyOverlayType deepCopy()/*-{
  return JSON.parse(JSON.stringify(this));
}-*/;

OR

public static native MyOverlayType fromJson(String json)/*-{
      return JSON.parse(json);
}-*/;
public native String getJson()/*-{
      return JSON.stringify(this);
}-*/;
public MyOverlayType deepCopy(){
      return fromJson(getJson());
}

The other option is a pure javascript approach which will maintain other stuff such as function pointers and probably be more efficient.

public class JsoUtils
{
    @SuppressWarnings("unchecked")
    public static <T extends JavaScriptObject> T deepCopy(T obj)
    {
        return (T) deepCopyImpl(obj);
    }

    private static native JavaScriptObject deepCopyImpl(JavaScriptObject obj)/*-{
        if (typeof obj !== 'object' || obj === null) {
            return obj;
        }

        var c = obj instanceof Array ? [] : {};

        for (var i in obj) {
            if (obj.hasOwnProperty(i)) {
                if (typeof obj[i] !== 'object' || obj[i] === null)
                    c[i] = obj[i];
                else
                    c[i] = @com.example.gwt.client.JsoUtils::deepCopyImpl(Lcom/google/gwt/core/client/JavaScriptObject;)(obj[i]);
            }
        }

        return c;
    }-*/;
}
Javier Ferrero

Based on Lineman78's answer and taking into consideration this other answer from A. Levy I created the following function:

public class JsoUtils {

    @SuppressWarnings("unchecked")
    public static <T extends JavaScriptObject> T deepCopy(T obj)
    {
        return (T) deepCopyImpl(obj);
    }

    private static native JavaScriptObject deepCopyImpl(JavaScriptObject obj) /*-{

        if (obj == null) return obj;

        var copy;        

        if (obj instanceof Date) {
            // Handle Date
            copy = new Date();
            copy.setTime(obj.getTime());
        } else if (obj instanceof Array) {
             // Handle Array
            copy = [];
            for (var i = 0, len = obj.length; i < len; i++) {
                if (obj[i] == null || typeof obj[i] != "object") copy[i] = obj[i];
                else copy[i] = @com.amindea.noah.client.utils.JsoUtils::deepCopyImpl(Lcom/google/gwt/core/client/JavaScriptObject;)(obj[i]);
            }
        } else {
            // Handle Object
            copy = {};
            for (var attr in obj) {
                if (obj.hasOwnProperty(attr)) {
                    if (obj[attr] == null || typeof obj[attr] != "object") copy[attr] = obj[attr];
                    else copy[attr] = @com.amindea.noah.client.utils.JsoUtils::deepCopyImpl(Lcom/google/gwt/core/client/JavaScriptObject;)(obj[attr]);
                }
            }
        }        
        return copy;
    }-*/;

} 

It supports deep copy of Object, Array, Date, String, Number, or Boolean. As explained by A. Levy the function will work as long as the data in the objects and arrays form a tree structure.

I found the simplest way to clone a JavaScriptObject is using the JsonUtils class provided by GWT:

import com.google.gwt.core.client.JsonUtils;

final String taskJson = JsonUtils.stringify(selectedTask);
TaskJso task = JsonUtils.safeEval(taskJson).cast();
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!