Javascript 网格的字段绑定。将新记录添加到存储后,视图仍不一致

Javascript 网格的字段绑定。将新记录添加到存储后,视图仍不一致,javascript,java,gridview,gwt,gxt,Javascript,Java,Gridview,Gwt,Gxt,我们在应用程序中为一些典型的网格用法实现了一个绑定。它工作得很好,除非您修改一个存储,例如添加一条记录,您将在视图中看到n+两条相同的记录。 当我检查存储的状态时,它显示了n+1个值 这就像我有一个网格,其中显示了一条记录,并调用:grid.getStore().add(modelFactory.createModel(event.getBean())我现在有: 第二行和第三行相等,无法选择第三行。此外,它不存在于grid.getStore()中 资料来源: freqsGrid = new A

我们在应用程序中为一些典型的网格用法实现了一个绑定。它工作得很好,除非您修改一个存储,例如添加一条记录,您将在视图中看到n+两条相同的记录。 当我检查存储的状态时,它显示了n+1个值

这就像我有一个网格,其中显示了一条记录,并调用:
grid.getStore().add(modelFactory.createModel(event.getBean())我现在有:

第二行和第三行相等,无法选择第三行。此外,它不存在于
grid.getStore()

资料来源:

freqsGrid = new AwesomeGridPanel() {
    @Override
    public void createColumns() {/**/}
};
freqBinding = AwesomeGridBinding.createGridBinding(freqsGrid, "frequencies");
简单绑定源。它按原样将模型的列表属性映射到网格

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

我发现解决这个问题的唯一方法是避免商店修改。 我用的是豆豆模型

小部件:

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

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()));
    }
});   
eventBus.addBeanCreatedEventHandler(RcTaskSchedule.class,NavigationTarget.RC_TASK_SCHEDULE_对话框,new BeanCreatedEvent.Handler()){
@凌驾
BeanCreated上的公共无效(BeanCreateEvent事件){
ListBinding.addListItemInBeanModel(display.getBeanModel(),“schedules”,schedulesFactory.createModel(event.getBean());
}
});
eventBus.addBeanModifiedEventHandler(RcTaskSchedule.class,NavigationTarget.RC_TASK_SCHEDULE_对话框,new BeanModifiedEvent.Handler()){
@凌驾
BeanModified上的公共无效(BeanModifiedEvent事件){
ListBinding.UpdateListItemBeanModel(display.getBeanModel(),“schedules”,
schedulesFactory.createModel(event.getOldBean()),schedulesFactory.createModel(event.getModifiedBean());
}
});   

公共类ListBinding扩展了FieldBinding{
私有电网;
私有ChangeListener=null;
私有MemoryProxy MemoryProxy=null;
公共ListBinding(网格、字符串属性){
超级(新AdapterField(电网),财产);
this.grid=grid;
if(!(grid.getStore().getLoader()实例BaseListLoader))
返回;
BaseListLoader=(BaseListLoader)grid.getStore().getLoader();
if(!(loader.getProxy()instanceof MemoryProxy))
返回;
memoryProxy=(memoryProxy)loader.getProxy();
}
@凌驾
公共void绑定(ModelData模型){
超级绑定(模型);
if(memoryProxy==null)
返回;
grid.getStore().removeAll();
setData(getModel().get(getProperty());
grid.getStore().getLoader().load();
if(!(BeanModel的模型实例))
返回;
BeanModel bm=(BeanModel)模型;
listener=新的ChangeListener(){
@凌驾
公共无效模型已更改(ChangeEvent事件){
if(!(PropertyChangeEvent的事件实例))
返回;
如果(!property.equals(((PropertyChangeEvent)事件).getName())
返回;
grid.getStore().removeAll();
setData(getModel().get(getProperty());
grid.getStore().getLoader().load();
}
};
bm.addChangeListener(监听器);
}
@凌驾
公共无效解除绑定(){
super.unbind();
grid.getStore().removeAll();
if(侦听器==null)
返回;
if(!(BeanModel的this.getModel()实例))
返回;
BeanModel bm=(BeanModel)this.getModel();
bm.removeChangeListener(监听器);
}
公共静态ListStore createEmptyStore(){
返回新的ListStore(新的BaseListLoader(新的MemoryProxy(新的BoundList())/*,新的BeanModelReader()*/);
}
公共静态void addListItemInBeanModel(BeanModel BeanModel,String属性,BeanModel newItem){
if(beanModel==null | |!(beanModel.get(property)instanceof List)| | newItem==null)
返回;
List List=beanModel.get(属性);
列表。添加(新项);
beanModel.set(属性,null);
beanModel.set(属性,列表);
}
公共静态void updateListItemBeanModel(BeanModel BeanModel、字符串属性、BeanModel oldItem、BeanModel newItem){
if(beanModel==null | | |!(beanModel.get(property)instanceof List)| | newItem==null | | oldItem==null)
返回;
List List=beanModel.get(属性);
int index=list.indexOf(oldItem);
如果(指数<0)
返回;
list.set(索引,newItem);
beanModel.set(属性,列表);
}
公共静态void removeListItemsInBeanModel(BeanModel BeanModel、字符串属性、列表项){
if(beanModel==null | |!(beanModel.get(property)instanceof List)| | items==null | | items.isEmpty())
返回;
List List=beanModel.get(属性);
列表。移除所有(项目);
beanModel.set(属性,列表);
}
}

我没有使用gwt/gxt的经验,所以出于好奇-在您的
setValue
方法中,您在调用
setResult
之前禁用更改监视和事件触发,原因是什么?@Sva.Mu另一个选项是陷入递归和堆栈溢出导致setValue更改存储,它触发事件,事件导致setValue。该症状听起来像是多个事件处理程序响应事件。我对gwt/gxt或Java不够熟悉,无法深入了解细节,但
super.handleEvent
可能会吸引我的眼球。您是否在方法中设置了断点,该方法将每一行写入网格,以便在每次触发调用堆栈时检查调用堆栈?您使用的是哪个版本的og GXT?肯定有多个事件处理程序。当我添加一个元素时,OnAdd激发,然后OnChange from AdapterField定制处理程序。但是我挂起setValue()中的所有处理程序。我无法定义在OnChange之前挂起事件并获取视图中的任何记录的任何方法。
@Override
public BeanModel getBeanModel() {
    return (BeanModel) formBinding.getModel();
}
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);
    }

}