2015-09-15 10 views
9

Abbiamo implementato un'associazione per alcuni tipici usi di Grid nell'applicazione. Funziona perfettamente, tranne se si modifica un negozio, ad esempio aggiungi un record, vedrai n + DUE record identici in vista. Quando ho esaminato lo stato del negozio, ha mostrato n + 1 valori.FieldBinding per Grid. La visualizzazione rimane incoerente dopo l'aggiunta di un nuovo record a Store

Esso va come se ho una griglia con un record mostrata in essa e chiamo: grid.getStore().add(modelFactory.createModel(event.getBean())); ora ho:

Second and third lines ARE equal

La seconda e la terza linea sono uguali e terzo non può essere selezionato. Inoltre, non è presente in grid.getStore().

Fonti:

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

semplice fonte vincolante. Associa la proprietà Elenco del modello alla griglia così com'è.

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

Se rimuovo la linea basso, vista fermate per mostrare n + 2 righe dopo aggiungono, e comincia a mostrare riga aggiunta anche dopo formBinding.bind(createModel(bean)); ad un altro bean.

+0

Non ho esperienza con gwt/gxt, quindi solo per curiosità: nel tuo metodo 'setValue' disabiliti il ​​monitoraggio delle modifiche e l'attivazione degli eventi prima di chiamare' setResult', qual è il motivo? –

+0

@ Sva.Mu Un'altra opzione è quella di ricadere nella ricorsione e l'overflow dello stack causa modifiche setValue Memorizza, genera eventi, gli eventi causano setValue. –

+0

Mi sembra che tu stia continuando a pulirti i dati ogni volta che aggiungi qualcosa. –

risposta

0

L'unico modo per risolvere il problema è evitare la modifica del negozio. Ho usato un BeanModel.

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

... Presentatore:

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

} 
Problemi correlati