CellTable 点击吞噬

CellTable click swallowed

我有一个组合框,它由一个文本字段和一个带有显示建议项的 CellTable 的弹出窗口组成。文本字段具有更新 CellTable 的选择的更改处理程序。

输入字符并单击已选择的建议时,第一次单击被吞没。第二次单击起作用并通过 CellTable.addDomHandler(...).

触发选择

知道为什么第一次点击被吞没了吗?

示例代码:

private static class SuggestFieldTextAndPopupSandbox extends SimplePanel {
        private final TextField mText;
        private CellTable<Handle<String>> mTable;
        private SingleSelectionModel<Handle<String>> mTableSelection;
        private SingleSelectionModel<Handle<String>> mSelection;
        private ProvidesKey<Handle<String>> mKeyProvider = new SimpleKeyProvider<Handle<String>>();
        private PopupPanel mPopup;
        private List<Handle<String>> mData;

        public SuggestFieldTextAndPopupSandbox() {
            mData = Lists.newArrayList(new Handle<String>("AAA"), new Handle<String>("AAB"), new Handle<String>("ABB"));
            mSelection = new SingleSelectionModel<Handle<String>>();

            mText = new TextField();
            mText.addKeyPressHandler(new KeyPressHandler() {
                @Override
                public void onKeyPress(KeyPressEvent pEvent) {
                    mPopup.showRelativeTo(mText);
                }
            });
            mText.addBlurHandler(new BlurHandler() {
                @Override
                public void onBlur(BlurEvent pEvent) {
                    mTableSelection.setSelected(startsWith(mText.getValue()), true);
                }
            });
            mText.addChangeHandler(new ChangeHandler() {

                @Override
                public void onChange(ChangeEvent pEvent) {
                    mText.setText(mText.getText().toUpperCase());
                }
            });

            mTable = new CellTable<Handle<String>>(0, GWT.<TableResources>create(TableResources.class));

            mTable.setTableLayoutFixed(false);
            mTableSelection = new SingleSelectionModel<Handle<String>>(mKeyProvider);
            mTable.setSelectionModel(mTableSelection);
            mTable.addDomHandler(new ClickHandler() {
                @Override
                public void onClick(final ClickEvent pEvent) {
                    Scheduler.get().scheduleFinally(new ScheduledCommand() {

                        @Override
                        public void execute() {
                            mSelection.setSelected(mTableSelection.getSelectedObject(), true);
                            mText.setFocus(true);
                            mPopup.hide();
                        }
                    });
                 }
            }, ClickEvent.getType());
            mTable.addColumn(new TextColumn<Handle<String>>() {
                @Override
                public String getValue(Handle<String> pObject) {
                    return pObject.get();
                }
            });
            mTable.setRowData(mData);

            mPopup = new PopupPanel();
            mPopup.setAutoHideEnabled(true);
            mPopup.setWidget(mTable);
            mPopup.setWidth("200px");
            mPopup.setHeight("200px");

            VerticalPanel p = new VerticalPanel();
            p.add(mText);
            setWidget(p);
        }

        private Handle<String> startsWith(final String pValue) {
            final String val = nullToEmpty(pValue).toLowerCase();
            int i = 0;
            for (Handle<String> item : mData) {
                String value = item.get();
                if (value != null && value.toLowerCase().startsWith(val)) {
                    return item;
                }
                i++;
            }
            return null;
        }

    }

我重现了你的问题,问题如下: 当您点击建议时,会发生以下情况:

  • 文本字段失去焦点,导致相应的 ChangeEvent 被处理,然后是 BlurEvent。
  • 点击导致弹出窗口现在获得焦点,这就是它被吞没的原因。

如果删除文本字段的 ChangeHandler 和 BlurHandler,问题就会消失。但我想我找到了另一个解决方案 尝试用相对于 mTab​​leSelection 的选择处理程序替换 mTab​​le 的 DOM 处理程序,如下所示:

mTableSelection.addSelectionChangeHandler(new Handler(){

            @Override
            public void onSelectionChange(SelectionChangeEvent event) {
                Scheduler.get().scheduleFinally(new ScheduledCommand() {

                    @Override
                    public void execute() {
                        mSelection.setSelected(mTableSelection.getSelectedObject(), true);
                        mText.setFocus(true);
                        mPopup.hide();
                    }
                });
            }

        });

找到了正确解决这个问题的方法。

当用户将鼠标悬停在建议列表区域时跳过模糊处理程序似乎可以解决该问题,至少从已完成的测试来看没有发现更多问题。

这是必要的,因为就在用户单击建议项之前,文本是模糊的并且会触发选择更改。这反过来会取消用户单击某个项目时所做的选择。