1

GXT のドキュメントで提供されている例よりも複雑な JSON 構造を持つサービスから返されたデータを処理する必要がありますが、これを実現する方法を示す指示や例は今のところ見つかりません。

JSON には複数のキーと値のペアが含まれていますが、キーと値のペアの一部はコレクションです。適切な構造のサービスから 1 回の呼び出しですべてのデータを返すことができますが、データを個別のエンティティに解析する方法はないようです。私の特定のケースでは、コレクションの 1 つを処理するローダーを構成しようとしていますが、同じメッセージから他のキーと値のペアも必要です (ローダーが 1 つの呼び出しを行ってから別の呼び出しを行うことは問題ありません)。同じデータを取得し、他のキーと値のペアを取得します)。GXT3 を使用してこれを達成する方法はありますか?

例: サーバーから、著者の名前とその著者が書いた本のコレクションを含む JSON を返すリクエストを作成できるとします。本をリストするグリッドの上に著者の名前を表示したいと思います。サーバーへのリクエストを 1 つだけ行い、作成者を 1 つのコンポーネントに表示し、本のリストをグリッドに表示するようにします。グリッドが追加の呼び出しを行う必要がある場合があるため (たとえば、ページング グリッド、ライブグリッドなどの場合)、単なるストアではなくローダーが必要であるとします。

JSON の例: (1 つの JSON メッセージが返され、author 要素と book 要素のコレクションが返されます - 構造を示すために JSON をインデントしています)

{ "returnData" : 
  {"author" : "AuthorName"}, 
  {"books" : 
     {"id" : "1", "name" : "Book1"},{"id" : "2", "name" : "Book2"}
  }
}

JsonReader の例 (例については javadoc を参照) を使用すると、要求を受け取り、AutoBeans を使用してリンクをコレクションに解析できます。ローダーでそれらを取得して解析する必要がある場合、これはうまく機能します。ただし、それを行うと、他のプロパティは無視されます。現在、同じリクエスト内の他の値を解析する方法が見当たらないため、他の場所で使用できます。コレクション処理のサンプル コードは次のとおりです。

// this is the root JSON object, the AuthorRecord
public interface AuthorRecord {
  @PropertyName(value="author")
  String getAuthor();
  @PropertyName(value="author")
  void setAuthor(String author);
  @PropertyName(value="books")
  List<Book> getBooks();@
  @PropertyName(value="books")
  void setBooks (List<Book> books);
}

// models the book objects returned
public interface Book {
 @PropertyName(value="id")
 String getId();
 @PropertyName(value="id")
 void setId(String id);
 @PropertyName(value="name")
 String getName();
 @PropertyName(value="name")
 void setName(String name);
}

public interface ReturnData {
  AuthorRootObject getAuthorRoot();
}

public interface LibraryAutoBeanFactory extends AutoBeanFactory {
  AutoBean<ReturnData> authorRecord();
 AutoBean<ListLoadConfig> loadConfig();
}

public class ReturnDataJsonReader extends JsonReader<ListLoadResult<Book>, 
  ReturnData> {
    public ReturnDataJsonReader(AutoBeanFactory factory, 
      Class<ReturnData> rootBeanType) {
        super(factory, rootBeanType);
    }

    @Override
    protected ListLoadResultBean<Book> createReturnData(Object loadConfig, 
      ReturnData incomingData) {
        return new ListLoadResultBean<Book>(incomingData.getBooks());
    }
}
4

1 に答える 1

1

私が抱えていた問題は、書籍を一覧表示するグリッド (ページング グリッドなど) を含むビューが必要であり、グリッドの上に著者の名前を表示する必要があることでした。JSONメッセージにはこれを達成するために必要なすべての情報が含まれているため、サーバーへの1回のリクエストでこのすべての情報(または少なくとも結果の最初のページ)を取得したかったのです。問題は、ローダーがリクエストを作成してレスポンスを受け取り、使用するリーダーがコレクションを処理することを期待していることです。私の場合、書籍のコレクションを処理するだけでなく、別のデータ フィールドを入力するローダーも必要です。私が見つけた解決策は、ローダーに渡す任意のコレクションを作成し、必要に応じて戻りオブジェクトを処理する独自のロード ハンドラーを実装することでした。

1. 返される JSON は、実際には ReturnData 型の 1 つのオブジェクトにすぎません。拡張された JsonReader は、AutoBeans を使用してこれを処理できますが、リーダーをローダーに使用する場合は、コレクションを返す必要があります。したがって、createReturnData() メソッドをオーバーライドして、1 つのオブジェクトのコレクションを返します。

public class ReturnDataJsonReader extends JsonReader<ListLoadResult<AuthorRecord>, 
  ReturnData> {

  public ReturnDataJsonReader(AutoBeanFactory factory, Class<ReturnData> rootBeanType) 
  {      
    super(factory, rootBeanType);   
  }    

  @Override   
  protected ListLoadResultBean<AuthorRecord> createReturnData(Object loadConfig,
      ReturnData incomingData) {       

    List<AuthorRecord> authorDataCollection = new ArrayList<AuthorRecord>();
    authorDataCollection.add(incomingData);
    return authorDataCollection;    
  }
}

2.例で使用されている LoadHandler は、ListStore を入力として受け取り、ローダーからの結果を入力します。返されたオブジェクトはローダーに入力したいものではなく、ビューに別のプロパティを入力する必要があるため、独自の LoadHandler を作成して、入力として必要なオブジェクトを取得して入力します。

ビュー クラスの例:

public class ExampleViewClass {
 // truncating most of the code in here for brevity
 // note some of the objects referenced here reference objects in the question
 private String authorName;
 private ListStore<Book> bookList;

 // IMPORTANT - create your own LoadHandler
 private class LibraryLoadResultistStoreBinding<C, M, D extends
    ListLoadResult<AuthorRecord>> implements LoadHandler<ListLoadConfig, 
    ListLoadResult<AuthorRecord>> {

      private final ListStore<Book> bookStore;
      private final String authorName;

      public LibraryLoadResultistStoreBinding(ListStore<Book> books, String author) {
          this.bookStore = books;
          this.authorName = author;
      }

      @Override
      public void onLoad(LoadEvent<ListLoadConfig, ListLoadResult<AuthorRecord> event) 
      {
        // the response object
        AuthorRecord response = event.getLoadResult().getData().get(0);  
        bookStore.replaceAll(response.getBooks());
        author = response.getAuthor();
      }
   }

   // example uses an HttpProxy but that's not required
   public void populateView() {
     LibraryAutoBeanFactory factory = GWT.create(LibraryAutoBeanFactory.class);
     ReturnDataJsonReader reader = new ReturnDataJsonReader(factory, ReturnData.class);
     String path = "http://path.to.resource/getinfo";
     RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, path);
     HttpProxy<ListLoadConfig> proxy = new HttpProxy<ListLoadConfig>(builder);

     final ListLoader<ListLoadConfig, ListLoadResult<AuthorRecord>> loader = new       
       ListLoader<ListLoadConfig, ListLoadResult<AuthorRecord>> (proxy, reader);

     loader.useLoadConfig(ReturnDataAutoBeanFactory.instance.loadConfig().as();

     loader.addLoadHandler(new LibraryLoadResultistStoreBinding<ListLoadConfig, 
       AuthorRecord, ListLoadResult<AuthorRecord>>(bookList, authorName);  
     // pass in the objects to be populated

     loader.load();  // fire the loader
   }
于 2012-12-31T14:37:17.997 に答える