2011-01-15 24 views
9

Tôi đang sử dụng CellBrowser của GWT 2.1 với tùy chỉnh TreeViewModel. TreeViewModel lần lượt sử dụng AsyncDataProvider để tìm nạp dữ liệu động. Điều này tất cả hoạt động rất đẹp - khi người dùng nhấp vào một nút mà AsyncDataProvider của tôi tìm nạp các kết quả thông qua RPC và trình duyệt CellBrowser hiển thị chúng một cách thận trọng.GWT: Làm thế nào để tải lại CellBrowser theo chương trình?

Tôi cảm thấy ngớ ngẩn vì không thể hình dung ra điều này, nhưng làm cách nào tôi có thể nói cho trình duyệt CellBrowser lập trình để tải lại (và hiển thị) dữ liệu? Tôi đoán rằng tôi cần bằng cách nào đó có được một xử lý cho AsyncDataProvider cho nút gốc của tôi và sau đó gọi updateRowData() & updateRowCount() trên đó, nhưng tôi không thấy một cách rõ ràng để truy vấn trình duyệt (hoặc mô hình của nó) cho DataProvider gốc.

Tôi đoán tôi có thể thêm mã vào hàm tạo AsyncDataProvider tìm kiếm đối số rỗng và điều đó có nghĩa là nhận ra "hey, tôi là root" và lưu trữ một tham chiếu ở đâu đó, nhưng điều đó có vẻ bị tấn công. Chắc chắn có một cách tốt hơn để làm điều này.

Xin lỗi vì đã đổ quá nhiều mã vào đây, nhưng tôi không biết cách đun sôi điều này xuống bất kỳ thứ gì đơn giản và vẫn cung cấp đủ ngữ cảnh.

AsyncDataProvider của tôi:

private static class CategoryDataProvider extends AsyncDataProvider<Category> 
{   
    private Category selectedCategory; 

    private CategoryDataProvider(Category selectedCategory) 
    { 
     this.selectedCategory = selectedCategory; 
    } 

    @Override 
    protected void onRangeChanged(HasData<Category> display) 
    { 
     new AsyncCall<List<Category>>() 
     { 
      @Override 
      protected void callService(AsyncCallback<List<Category>> cb) 
      { 
       // default to root 
       String categoryId = "-1"; 
       if (selectedCategory != null) 
       { 
        categoryId = selectedCategory.getCategoryId(); 
       } 

       // when a category is clicked, fetch its child categories 
       service.getCategoriesForParent(categoryId, cb); 
      } 

      @Override 
      public void onSuccess(List<Category> result) 
      { 
       // update the display 
       updateRowCount(result.size(), true); 
       updateRowData(0, result); 
      } 
     }.go(); 

    } 
} 

mô hình của tôi:

private static class CategoryTreeModel implements TreeViewModel 
{ 
    private SingleSelectionModel<Category> selectionModel; 

    public CategoryTreeModel(SingleSelectionModel<Category> selectionModel) 
    { 
     this.selectionModel = selectionModel; 
    } 

    /** 
    * @return the NodeInfo that provides the children of the specified category 
    */ 
    public <T> NodeInfo<?> getNodeInfo(T value) 
    { 
     CategoryDataProvider dataProvider = new CategoryDataProvider((Category) value); 

     // Return a node info that pairs the data with a cell. 
     return new TreeViewModel.DefaultNodeInfo<Category>(dataProvider, new CategoryCell(), selectionModel, null); 
    } 

    /** 
    * @return true if the specified category represents a leaf node 
    */ 
    public boolean isLeaf(Object value) 
    { 
     return value != null && ((Category) value).isLeafCategory(); 
    } 
} 

Và cuối cùng, đây là cách tôi đang sử dụng chúng:

 CategoryTreeModel model = new CategoryTreeModel(selectionModel); 
     CellBrowser cellBrowser = new CellBrowser(model, null); 

Trả lời

10

Có vẻ như rất nhiều người đang có số này same issue. Đây là cách tôi xử lý làm mới dữ liệu từ AsyncDataProvider.

Trước tiên, hãy tạo giao diện bổ sung khả năng làm mới nhà cung cấp dữ liệu bằng cách gói phương thức onRangeChanged được bảo vệ của AsyncDataProvider. Ví dụ ...

HasRefresh.java

public interface HasRefresh<HasData<T>>{ 
    /** 
    * Called when a display wants to refresh 
    * 
    * @param display the display to refresh 
    */ 
    void refresh(HasData<T> display); 

} 

Sau đó CellTable cần phải được làm mới sau đó có thể gọi vào nó thông qua một hoặc Hoạt động tuy nhiên Logic điều khiển của bạn được thiết lập.

/** 
* A custom {@link AsyncDataProvider}. 
*/ 
public class MyAsyncDataProvider extends 
      AsyncDataProvider<Entity> implements HasRefresh<Entity> { 

      public void refresh(Entity display){ 

        onRangeChanged(display); 
      } 

      /** 
     * {@link #onRangeChanged(HasData)} is called when the table requests a 
     * new range of data. You can push data back to the displays using 
     * {@link #updateRowData(int, List)}. 
     */ 
     @Override 
     protected void onRangeChanged(
       HasData<Entity> display) { 
      currentRange = display.getVisibleRange(); 
      final int start = currentRange.getStart(); 

      dataServiceQuery = context.getEntities(); 

      dataServiceQuery 
        .execute(new DataServiceQueryHandler<Entity>() { 

         @Override 
         public void onQueryResponse(
           DataServiceQueryResponse<Entity> response) { 


          updateRowCount(response.getCount(), true); 
          updateRowData(start, response.getEntities()); 

         } 
        }); 

     }// end onRangeChanged() 

    }// end MyAsyncDataProvider class 
+0

lỗi đánh máy trên "HashRefresh" nhưng nếu không +1! :) – HaveAGuess

+0

Tại sao mọi người bỏ phiếu cho câu trả lời này? Cái dưới đây là tốt hơn nhiều - một thay đổi dòng đơn mà làm tất cả những điều này. –

+0

updateRowData (start, response.getEntities()) cập nhật tất cả các hiển thị cho nhà cung cấp, bạn có thể sử dụng updateRowData (display, start, response.getEntities()) để thay thế. Nhưng display.setVisibleRangeAndClearData (display.getVisibleRange(), true) vẫn tốt hơn :) – Quiz

7

Phát hiện ra bây giờ, mã sau về cơ bản giống nhau nhưng từ giao diện HasData thay vì sử dụng AsyncDataProvider.

HasData<T> display; 
... 
display.setVisibleRangeAndClearData(display.getVisibleRange(), true); 
+0

Làm việc cho tôi! Cảm ơn! –

2

Tôi không hiểu tại sao câu trả lời của affablebloke được đánh dấu là "chính xác" và được bỏ phiếu rất nhiều !?

Caffeine Coma hỏi về việc cập nhật Trình duyệt di động và không phải là Bảng di động, đó là những điều hoàn toàn khác!

Đối với tôi, mẹo sau đã làm việc: Tôi xác định DataProvider s bên ngoài của TreeViewModel và chuyển chúng làm đối số cho hàm tạo. Trong trường hợp của tôi, chúng cung cấp các cấu trúc dữ liệu rỗng ngay từ đầu.

Bây giờ bạn có một tham chiếu đến DataProvider s từ "bên ngoài" để cập nhật Trình duyệt ô.

Ví dụ:

private class MyTreeViewModel implements TreeViewModel { 

    AbstractDataProvider<MyDataStructure> myDataProvider; 

    public MyTreeViewModel(AbstractDataProvider<MyDataStructure> myDataProvider) 
    { 
     this.myDataProvider = myDataProvider; 
    } 

    @Override 
    public <T> NodeInfo<?> getNodeInfo(T value) { 
     if(value == null) 
     { 
      // Level 0 
      return new DefaultNodeInfo<MyDataStructure>(myDataProvider, new MyCellImpl()); 
     } 
    } 
} 


AbstractDataProvider<MyDataStructure> myDataProvider = new ListDataProvider<MyDataStructure>(new ArrayList<MyDataStructure>()); // or AsyncDataProvider 
MyTreeViewModel myModel = new MyTreeViewModel(myDataProvider); 

CellBrowser<MyDataStructure> cellBrowser = new CellBrowser.Builder<MyDataStructure>(myModel, null).build(); 

/* 
    here you can do some stuff, for example, bind the CellBrowser to a template with UiBinder 
*/ 

/* 
if you use a ListDataProvider, do 
*/ 

myDataProvider.setList(myDataStructureFromSomewhere); 
myDataProvider.refresh(); 

/* 
if you use an AsyncDataProvider, do 
*/ 

myDataProvider.updateRowData(..., myDataStructureFromSomewhere); 
myDataProvider.updateRowCount(...); 
+0

Cảm ơn bạn đã cung cấp câu trả lời này. Nó hoạt động hoàn hảo. Tôi đã tự hỏi làm thế nào để làm mới một CellBrowser trong một thời gian. –

0

tôi đã cùng một vấn đề và điều này đã làm việc cho tôi:

List<TreeGridRecord> dataToTable = .... 

int firstPosition = this.pager.getDisplay().getVisibleRange().getStart(); 
this.dataProvider.updateRowData(firstPosition, dataToTable); 

int rowCount = this.pager.getPageStart() + dataToTable.size(); 
this.dataProvider.updateRowCount(rowCount, exactCount); 

Trường hợp "pager" là một SimplePager để kiểm soát pagination bảng.

Hy vọng điều này sẽ hữu ích!

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