2015-09-15 7 views
9

inkonsistent. Wir haben eine Bindung für einige typische Grid-Verwendungen in der Anwendung implementiert. Es funktioniert gut, außer, wenn Sie einen Speicher ändern, zum Beispiel einen Datensatz hinzufügen, würden Sie n + zwei identische Datensätze in Sicht sehen. Wenn ich den Zustand des Ladens untersuchte, zeigte es n + 1 Werte an.FieldBinding für Grid. Die Ansicht bleibt nach dem Hinzufügen eines neuen Datensatzes zu Store

Es geht, als ob ich ein Gitter mit einem Datensatz in gezeigt haben und rufen: grid.getStore().add(modelFactory.createModel(event.getBean())); Ich habe jetzt:

Second and third lines ARE equal

Die zweite und die dritte Zeile gleich sind und dritte nicht sein kann ausgewählt. Auch ist es in grid.getStore() nicht anwesend.

Quellen:

freqsGrid = new AwesomeGridPanel() { 
    @Override 
    public void createColumns() {/**/} 
}; 
freqBinding = AwesomeGridBinding.createGridBinding(freqsGrid, "frequencies"); 

Einfache Bindung Quelle. Er weist die List-Eigenschaft des Modells dem Grid zu, wie es ist.

public class AwesomeGridBinding { 
    public static FieldBinding createGridBinding(AwesomeGridPanel grid, String property) { 
     return new FieldBinding(new AwesomeGridAdapterField(grid), property); 
    } 
} 

class AwesomeGridAdapterField<T> extends AdapterField { 

    protected AwesomeGridPanel grid; 
    private StoreListener<BeanModel> storeChangedListener; 

    public AwesomeGridAdapterField(AwesomeGridPanel grid) { 
     super(grid); 
     this.grid = grid; 
     configureGrid(grid, this); 
    } 

    @Override 
    public void setValue(Object value) { 
     List data; 
     if (value == null) 
      data = new ArrayList<>(); 
     else if (!(value instanceof List)) 
      throw new IllegalArgumentException(); 
     else 
      data = (List) value; 
     grid.getStore().setMonitorChanges(false); 
     grid.getStore().setFiresEvents(false); 
     setResults(grid.getStore(), data); 
     grid.getStore().setFiresEvents(true); 
     grid.getStore().setMonitorChanges(true); 

Wenn ich die folgende Zeile zu entfernen, hält Ansicht n + 2 Zeilen nach hinzufügen, um zu zeigen, und beginnt hinzugefügt Linie auch auf eine andere Bohne nach formBinding.bind(createModel(bean)); zu zeigen.

 grid.getGrid().getView().refresh(false); 
    } 

    @Override 
    public Object getValue() { 
     List<T> result = new ArrayList<>(); 
     for (BeanModel bm : grid.getStore().getModels()) 
      if (isBeanForResult(bm)) 
       result.add(extractResult(bm)); 
     return result; 
    } 

    protected void setResults(ListStore<BeanModel> store, List data) { 
     store.removeAll(); 
     for (Object obj : data) 
      if (obj instanceof BeanModel) 
       store.add((BeanModel) obj); 
      else 
       throw new IllegalArgumentException(); 
    } 

    protected boolean isBeanForResult(BeanModel beanModel) { 
     return true; 
    } 

    protected T extractResult(BeanModel bmFromStore) { 
     return bmFromStore.getBean(); 
    } 

    private final EventType[] STORE_EVENTS = {Store.Add, Store.Clear, Store.DataChanged, Store.Remove, Store.Update}; 

    protected void configureGrid(final AwesomeGridPanel grid, final AdapterField field) { 
     grid.getStore().setMonitorChanges(true); 
//  grid.getStore().removeAllListeners(); 
     if (storeChangedListener != null) 
      grid.getStore().removeStoreListener(storeChangedListener); 

     storeChangedListener = new StoreListener<BeanModel>() { 
      @Override 
      public void handleEvent(StoreEvent<BeanModel> e) { 
       super.handleEvent(e); 
       for (EventType se : STORE_EVENTS) { 
        if (se != e.getType()) 
         continue; 
        field.fireEvent(Events.Change); 
        return; 
       } 
      } 
     }; 
     grid.getStore().addStoreListener(storeChangedListener); 
    } 
} 
+0

Ich habe keine Erfahrung mit gwt/gxt, also nur aus Neugier - in deiner 'setValue' Methode deaktivierst du die Änderung der Überwachung und das Auslösen von Ereignissen vor dem Aufruf von' setResult', was ist der Grund? –

+0

@ Sva.Mu Eine weitere Option ist es, in Rekursion und Stack-Überlauf zu fallen, da setValue-Änderungen Store, es feuert Ereignisse, Ereignisse verursacht setValue. –

+0

Es scheint mir, als würden Sie Ihre Daten ständig sauber machen, jedes Mal wenn Sie etwas hinzufügen. –

Antwort

0

Die einzige Möglichkeit, das Problem zu beheben, ist die Speicheränderung zu vermeiden. Ich habe ein BeanModel verwendet.

Widget:

schedulesGridPanel = new AwesomeGridView<RcTaskSchedule>(ListBinding.createEmptyStore(), NavigationTarget.RADIOCONTROL_TASK_DIALOG, "RCTaskDialogSchedulesGridPanel") { 
    @Override 
    public void createColumns() {...} 
}; 
formBinding.addFieldBinding(new ListBinding(schedulesGridPanel.getGrid(), "schedules")); 

...

@Override 
public BeanModel getBeanModel() { 
    return (BeanModel) formBinding.getModel(); 
} 

... Moderator:

eventBus.addBeanCreatedEventHandler(RcTaskSchedule.class, NavigationTarget.RC_TASK_SCHEDULE_DIALOG, new BeanCreatedEvent.Handler<RcTaskSchedule>() { 
    @Override 
    public void onBeanCreated(BeanCreatedEvent<RcTaskSchedule> event) { 
     ListBinding.addListItemInBeanModel(display.getBeanModel(), "schedules", schedulesFactory.createModel(event.getBean())); 
    } 
}); 

eventBus.addBeanModifiedEventHandler(RcTaskSchedule.class, NavigationTarget.RC_TASK_SCHEDULE_DIALOG, new BeanModifiedEvent.Handler<RcTaskSchedule>() { 
    @Override 
    public void onBeanModified(BeanModifiedEvent<RcTaskSchedule> event) { 
     ListBinding.updateListItemInBeanModel(display.getBeanModel(), "schedules", 
       schedulesFactory.createModel(event.getOldBean()), schedulesFactory.createModel(event.getModifiedBean())); 
    } 
}); 

...

public class ListBinding extends FieldBinding { 

    private Grid grid; 
    private ChangeListener listener = null; 
    private MemoryProxy memoryProxy = null; 

    public ListBinding(Grid grid, String property) { 
     super(new AdapterField(grid), property); 
     this.grid = grid; 
     if (!(grid.getStore().getLoader() instanceof BaseListLoader)) 
      return; 
     BaseListLoader loader = (BaseListLoader) grid.getStore().getLoader(); 
     if (!(loader.getProxy() instanceof MemoryProxy)) 
      return; 
     memoryProxy = (MemoryProxy) loader.getProxy(); 
    } 

    @Override 
    public void bind(ModelData model) { 
     super.bind(model); 

     if (memoryProxy == null) 
      return; 
     grid.getStore().removeAll(); 
     memoryProxy.setData(getModel().get(getProperty())); 
     grid.getStore().getLoader().load(); 

     if (!(model instanceof BeanModel)) 
      return; 
     BeanModel bm = (BeanModel) model; 

     listener = new ChangeListener() { 
      @Override 
      public void modelChanged(ChangeEvent event) { 
       if (!(event instanceof PropertyChangeEvent)) 
        return; 
       if (!property.equals(((PropertyChangeEvent) event).getName())) 
        return; 
       grid.getStore().removeAll(); 
       memoryProxy.setData(getModel().get(getProperty())); 
       grid.getStore().getLoader().load(); 
      } 
     }; 
     bm.addChangeListener(listener); 
    } 

    @Override 
    public void unbind() { 
     super.unbind(); 
     grid.getStore().removeAll(); 
     if (listener == null) 
      return; 
     if (!(this.getModel() instanceof BeanModel)) 
      return; 
     BeanModel bm = (BeanModel) this.getModel(); 
     bm.removeChangeListener(listener); 
    } 

    public static ListStore<BeanModel> createEmptyStore() { 
     return new ListStore<>(new BaseListLoader(new MemoryProxy(new BoundList<>())/*, new BeanModelReader()*/)); 
    } 

    public static void addListItemInBeanModel(BeanModel beanModel, String property, BeanModel newItem) { 
     if (beanModel == null || !(beanModel.get(property) instanceof List) || newItem == null) 
      return; 
     List<BeanModel> list = beanModel.get(property); 
     list.add(newItem); 
     beanModel.set(property, null); 
     beanModel.set(property, list); 
    } 

    public static void updateListItemInBeanModel(BeanModel beanModel, String property, BeanModel oldItem, BeanModel newItem) { 
     if (beanModel == null || !(beanModel.get(property) instanceof List) || newItem == null || oldItem == null) 
      return; 
     List<BeanModel> list = beanModel.get(property); 
     int index = list.indexOf(oldItem); 
     if (index < 0) 
      return; 
     list.set(index, newItem); 
     beanModel.set(property, list); 
    } 

    public static void removeListItemsInBeanModel(BeanModel beanModel, String property, List<BeanModel> items) { 
     if (beanModel == null || !(beanModel.get(property) instanceof List) || items == null || items.isEmpty()) 
      return; 
     List<BeanModel> list = beanModel.get(property); 
     list.removeAll(items); 
     beanModel.set(property, list); 
    } 

}