GWT Overlay глубокая копия - PullRequest
2 голосов
/ 19 января 2011

Какой лучший способ сделать глубокую копию типа оверлея gwt?

Я ищу функцию или библиотеку, которая проверяет оверлей GWT и клонирует его. Он должен быть способен клонировать содержащиеся массивы или объекты.

Спасибо

Ответы [ 3 ]

5 голосов
/ 19 января 2011

Есть 2 способа, которые я бы рассмотрел. Большую часть времени оверлейные объекты используются вместе с JSON, так что вы можете просто привести в порядок объект и проанализировать результаты:

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());
}

Другой вариант - это чистый JavaScript-подход, который будет поддерживать другие вещи, такие как указатели функций, и, вероятно, будет более эффективным.

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;
    }-*/;
}
2 голосов
/ 19 января 2011

На основе ответа Lineman78 и с учетом этого другого ответа от А. Леви Я создал следующую функцию:

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;
    }-*/;

} 

Поддерживает глубокое копирование Object, Array, Date, String, Number или Boolean. Как объясняется A. Леви функция будет работать до тех пор, пока данные в объектах и ​​массивах образуют древовидную структуру.

0 голосов
/ 17 ноября 2015

Я обнаружил, что самый простой способ клонировать JavaScriptObject - это использовать класс JsonUtils, предоставленный GWT:

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

final String taskJson = JsonUtils.stringify(selectedTask);
TaskJso task = JsonUtils.safeEval(taskJson).cast();
...