2010-06-26 42 views
7

Trong GWT, tôi có một mã JsArray <JavaScriptObject> trong mã của mình. Đó là nhiều hơn hoặc ít hơn một danh sách các đối tượng JSON, nhưng loại của nó là JsArray <JavaScriptObject>. Về cơ bản nó phải ở định dạng này, bởi vì tôi chuyển nó thành một tham số cho một số mã JavaScript bên ngoài bằng cách sử dụng JSNI. Rắc rối là, tôi cũng muốn giá trị này được sử dụng bởi mã Java. Trong Java, tôi muốn đối phó với một đối tượng thuộc loại <JSONObject>. Tuy nhiên, tôi đã không thực sự tìm thấy một cách tốt để chuyển đổi giữa hai điều này. Điều tốt nhất tôi có thể làm là đi bộ thẳng qua mảng để tạo loại mới tôi muốn:Chuyển đổi từ JsArray <JavaScriptObject> thành Danh sách <JSONObject> trong GWT

public List<JSONObject> getData() { 
    LinkedList<JSONObject> list = new LinkedList<JSONObject>(); 
    for (int i = 0; i < data.length(); ++i) { 
    list.add(new JSONObject(data.get(i))); 
    } 
    return list; 
    } 

Tôi có may mắn không? Hoặc là có một cách nhanh chóng tốt đẹp để có được giữa hai loại?

(Trả về một giá trị JSONArray có lẽ cũng sẽ ổn ... nhưng một cái gì đó thực hiện giao diện Danh sách thì đẹp).

Trả lời

5

Lý do tại sao bạn không thể dễ dàng truyền JsArray cho bất kỳ triển khai Java nào của giao diện List là vì JsArray chỉ là một trình bao bọc xung quanh một mảng JavaScript tốt. Điều này cho phép một số hoạt động rất nhanh trên nó (vì JSON là một phần của JS), nhưng với chi phí không "tương thích" với phần còn lại của mã "Java". Vì vậy, bạn phải tự hỏi mình nếu tốc độ là một yếu tố quan trọng và bạn sẽ mất bao nhiêu nếu bạn chuyển đổi sang danh sách "Java" (tất nhiên, nội bộ sẽ chỉ là một mảng JS).

AFAIR, tôi đã không thể tìm thấy bất kỳ giải pháp thanh lịch nào cho tình huống này - nhưng trong trường hợp của tôi, tôi đã sử dụng các đối tượng JsArray ngay lập tức để tạo POJO và vượt qua những điểm đó.

-2

Tôi khá chắc chắn, bạn đã thử phương thức JSONObject.cast().

3

Chúng tôi đã triển khai một trình bao bọc đơn giản xung quanh JsArray chỉ hỗ trợ một vài phương pháp. Nếu bạn không cần tất cả chức năng của Danh sách:

public class JsArrayList<T> implements List<T> { 

    private final JsArray<? extends T> array; 

    public JsArrayList(final JsArray<? extends T> array) { 
     this.array = array; 
    } 

    public boolean add(final T e) { 
     throw new RuntimeException("Not implemented."); 
    } 

    public boolean isEmpty() { 
     return this.size() == 0; 
    } 

    public Iterator<T> iterator() { 
     if (array == null) { 
     return new EmptyIterator<T>(); 
    } else { 
     return new JsArrayIterator<T>(array); 
    } 
    } 

    public int size() { 
     if (array == null) return 0; 
     return array.length(); 
    } 

    public T get(final int index) { 
     if (array == null) { throw new IndexOutOfBoundsException("array is emtpy"); } 
     return array.get(index); 
    } 

    ... 
} 

Đây là giải pháp hiệu quả nhất và thanh lịch mà chúng tôi đã tìm thấy.

+0

Bạn có thể chia sẻ việc triển khai đầy đủ không? Cảm ơn bạn! –

+0

Phần còn lại của lớp khá giống với cách tôi đã đăng. Nó chỉ là quá dài cho câu trả lời này. –

2

Làm việc từ ý tưởng @EduardWirch của lớp bao bọc mà tôi đã tạo JsList sử dụng và phiên bản mở rộng của JsArray, để xử lý hầu hết mã, bạn có thể lấy ở đây JsList. Nó cho phép tạo JsList qua JsArrayExtend như vậy:

public class Values extends JavaScriptObject 
{ 
    protected Values(){}; 
    static public final native JsArrayExtend getValues(String json) /*-{return eval('('+json+')');}-*/; 
} 

public class Value extends JavaScriptObject 
{ 
    protected Value(){} 

    public final native String getName() /*-{return this.name;}-*/; 
} 

... 

JsList<Value> valueList=JsList<Value>(Values.getList(jsonString)); 

này có thể được làm thức ăn cho bất kỳ đối tượng mà sẽ đưa Danh sách <> và dường như làm việc tốt. Tôi đã không kiểm tra kỹ lưỡng nó vì vậy nếu bạn thấy bất kỳ vấn đề cho tôi biết và tôi sẽ cập nhật nó.

Ban đầu tôi đã tạo một loại JavaScriptObject sử dụng mã gốc để hoạt động giống như danh sách bạn có thể xem tại đây JsList extends JavaScriptObject, tuy nhiên nó phá vỡ hệ thống nhập GWT và mặc dù nó hoạt động để biên dịch Javascript không hoạt động.

1

Turbo GWT Core cung cấp giải pháp thanh lịch cho nó. Bên trong gói Js.Collections của nó, có JsArrayList, một danh sách liệt kê gói JS nguyên gốc. Nhiều phương pháp của hợp đồng được kiểm tra và hoạt động như mong đợi. Ngoài ra, nó hoạt động với bất kỳ loại đối tượng nào, không chỉ các loại Lớp phủ.

Bạn có thể quấn trực tiếp JsArray như List myList = new JsArrayList(jsArray).

Turbo GWT Js.Collections cũng cung cấp triển khai JsArray riêng với nhiều phương thức hơn và hỗ trợ bất kỳ đối tượng nào. Có một JsArrayIterator, để lặp qua JsArrays.

Bạn có thể tìm thêm tại https://github.com/growbit/turbogwt-core.

Các vấn đề liên quan