2011-01-15 13 views
9

मैं कस्टम TreeViewModel के साथ जीडब्ल्यूटी 2.1 के CellBrowser का उपयोग कर रहा हूं। बदले में TreeViewModel डेटा को गतिशील रूप से लाने के लिए AsyncDataProvider का उपयोग करता है। यह सब खूबसूरती से काम करता है- जब उपयोगकर्ता नोड पर क्लिक करता है तो मेरा AsyncDataProvider आरपीसी के माध्यम से परिणाम प्राप्त करता है, और सेलब्रोसर कर्तव्यपूर्वक उन्हें प्रदर्शित करता है।जीडब्ल्यूटी: प्रोग्रामब्रेटिक रूप से सेलब्रोसर को फिर से लोड कैसे करें?

मुझे यह समझने में सक्षम नहीं होने के लिए मूर्खतापूर्ण लगता है, लेकिन मैं डेटाब्राउज़र को डेटा को पुनः लोड (और प्रदर्शित) करने के लिए प्रोग्रामेटिक रूप से कैसे बता सकता हूं? मुझे लगता है कि मुझे किसी भी तरह से मेरे रूट नोड के लिए AsyncDataProvider को एक हैंडल प्राप्त करने की आवश्यकता है और उसके बाद UpdateRowData() & UpdateRowCount() पर कॉल करें, लेकिन मुझे ब्राउज़र (या उसके मॉडल) से पूछताछ करने का एक स्पष्ट तरीका दिखाई नहीं देता है। रूट डेटाप्रोवाइडर के लिए।

मुझे लगता है कि मैं अपने असिनकडाटाप्रोवाइडर कन्स्ट्रक्टर को कोड जोड़ सकता हूं जो एक शून्य तर्क की तलाश में है, और इसका मतलब है "अरे, मैं रूट हूं" और कहीं एक संदर्भ संग्रहीत करता हूं, लेकिन यह हैक लगता है। निश्चित रूप से ऐसा करने का एक बेहतर तरीका है।

यहां बहुत अधिक कोड डंप करने के लिए क्षमा चाहते हैं, लेकिन मुझे नहीं पता कि इसे किसी भी चीज़ को सरल कैसे उबालें और अभी भी पर्याप्त संदर्भ प्रदान करें।

मेरे AsyncDataProvider:

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

    } 
} 

मेरे मॉडल:

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

और अंत में, यहाँ मैं उन्हें कैसे उपयोग कर रहा हूँ है:

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

उत्तर

10

ऐसा लगता है कि बहुत से लोगों को यह same issue है। यहां बताया गया है कि मैंने एक AsyncDataProvider से डेटा को रीफ्रेश करने का तरीका कैसे संभाला।

सबसे पहले, एक इंटरफ़ेस बनाएं जो AsyncDataProvider की संरक्षित ऑनरेंज चेंज विधि को लपेटकर डेटा प्रदाता को रीफ्रेश करने की क्षमता को जोड़ता है। उदाहरण के लिए ...

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

} 

फिर CellTable ताज़ा करने तो एक गतिविधि या फिर भी अपने नियंत्रक तर्क सेटअप है के माध्यम से इसे में कॉल कर सकते हैं की जरूरत है।

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

"हैशरफ्रेश" पर टाइपो लेकिन अन्यथा +1! :) – HaveAGuess

+0

हर कोई इस जवाब को क्यों वोट दे रहा है? नीचे दिया गया एक बहुत बेहतर है - एक पंक्ति परिवर्तन जो यह सब करता है। –

+0

अद्यतनरोडाटा (प्रारंभ, प्रतिक्रिया.getEntities()) प्रदाता के लिए सभी डिस्प्ले अपडेट करें, आप इसके बजाय UpdateRowData (प्रदर्शन, प्रारंभ, प्रतिक्रिया.getEntities()) का उपयोग कर सकते हैं। लेकिन display.setVisibleRangeAndClearData (display.getVisibleRange(), true) अभी भी बेहतर है :) – Quiz

7

अब पता चला, निम्नलिखित कोड मूलतः एक ही है, लेकिन इसके बजाय AsyncDataProvider का उपयोग करने का HasData इंटरफ़ेस से।

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

मेरे लिए काम करता है! धन्यवाद! –

2

मुझे समझ नहीं आता क्यों affablebloke का जवाब "सही" के रूप में चिह्नित और इतना upvoted है !?

कैफीन कोमा एक सेल ब्राउज़र और नहीं एक सेल टेबल को अद्यतन करने, कि पूरी तरह से अलग बातें हैं के बारे में पूछा!

मेरे लिए, निम्न चाल काम किया: मैं DataProvider रों TreeViewModel के बाहर परिभाषित करने और उन्हें निर्माता के लिए एक तर्क के रूप गुजरती हैं। मेरे मामले में वे शुरुआत में खाली डेटा संरचनाएं प्रदान करते हैं।

अब सेल ब्राउज़र को अपडेट करने के लिए आपके पास "बाहर" से DataProvider एस का संदर्भ है।

उदाहरण:

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

धन्यवाद यह उत्तर देने के लिए धन्यवाद। यह पूरी तरह से काम करता है। मैं सोच रहा था कि सेलब्राउज़र को थोड़ी देर के लिए रीफ्रेश कैसे करें। –

0

मैं एक ही समस्या थी और यह मेरे लिए काम किया:

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

कहाँ "पेजर" एक SimplePager तालिका पृष्ठांकन नियंत्रित करने के लिए है।

आशा है कि इससे मदद मिलती है!

संबंधित मुद्दे