【问题标题】:GWT Header CheckBox requires two clicks to fire setValue, after changing its value programatically在以编程方式更改其值后,GWT Header CheckBox 需要两次单击才能触发 set Value
【发布时间】:2013-08-01 23:18:12
【问题描述】:

我有一个 GWT DataGrid,并且在标题中有一个 CheckBox,用于选择/取消选择网格中的所有行。

CheckBox Header的代码如下:

    private class CheckboxHeader extends Header<Boolean> implements HasValue<Boolean> {

    private boolean checked;
    private HandlerManager handlerManager;

    /**
     * An html string representation of a checked input box.
     */
    private final SafeHtml INPUT_CHECKED = SafeHtmlUtils.fromSafeConstant("<input type=\"checkbox\" tabindex=\"-1\" checked/>");
    /**
     * An html string representation of an unchecked input box.
     */
    private final SafeHtml INPUT_UNCHECKED = SafeHtmlUtils.fromSafeConstant("<input type=\"checkbox\" tabindex=\"-1\"/>");

    @Override
    public void render(Context context, SafeHtmlBuilder sb) {
        if (Boolean.TRUE.equals(this.getValue())) {
            sb.append(INPUT_CHECKED);
        } else {
            sb.append(INPUT_UNCHECKED);
        }
    };

    public CheckboxHeader() {
        super(new CheckboxCell(true, false));
        checked = true;
    }

    // This method is invoked to pass the value to the CheckboxCell's render method
    @Override
    public Boolean getValue() {
        return checked;
    }

    @Override
    public void onBrowserEvent(Context context, Element elem, NativeEvent nativeEvent) {
        int eventType = Event.as(nativeEvent).getTypeInt();
        if (eventType == Event.ONCHANGE) {
            nativeEvent.preventDefault();
            // use value setter to easily fire change event to handlers
            setValue(!checked, true);
        }
    }

    @Override
    public HandlerRegistration addValueChangeHandler(ValueChangeHandler<Boolean> handler) {
        return ensureHandlerManager().addHandler(ValueChangeEvent.getType(), handler);
    }

    @Override
    public void fireEvent(GwtEvent<?> event) {
        ensureHandlerManager().fireEvent(event);
    }

    @Override
    public void setValue(Boolean value) {
        setValue(value, true);
    }

    @Override
    public void setValue(Boolean value, boolean fireEvents) {
        checked = value;
        if (fireEvents) {
            ValueChangeEvent.fire(this, value);
        }
    }

    private HandlerManager ensureHandlerManager() {
        if (handlerManager == null) {
            handlerManager = new HandlerManager(this);
        }
        return handlerManager;
    }
}

因此,我将 Header 添加到网格中,并添加 ValueChangeHandler 以在网格的每一行中实际选择/取消选择单个 CheckBox 单元格。这一切都有效。

每个CheckBoxCell 都有一个字段更新器,在每次更新时,它都会遍历网格中的每个项目以查看它们是否都被选中,并更新标题复选框。如果至少有一个未选中,则标题复选框将未选中。我在标题复选框上调用setValue(),然后在整个网格上调用redrawHeaders()。这也有效。

不起作用的是 - 在以编程方式更改标题复选框的“状态”后,需要单击两次才能再次触发它的内部 setValue,从而触发我的处理程序。更有趣的是——第一次点击确实改变了复选框的状态,但它不会触发事件。

任何帮助将不胜感激。

【问题讨论】:

    标签: gwt checkbox datagrid celltable


    【解决方案1】:

    您如何自己构建 CheckboxCells?我遇到了一列复选框“吃”点击的类似问题,解决方案是调用CheckboxCell cell = new CheckboxCell(true,true),然后将该单元格传递给该列的构造函数。

    【讨论】:

    • 忘了提了,已经试过了......而且这两个布尔值的几乎所有组合。总是需要两次点击才能触发事件,即使复选框本身确实改变了它的状态。
    • 对于它的价值,我们已经实现了一个带有标题的复选框列,它通过以下方式选择/取消选择所有元素:CheckboxCell cell = new CheckboxCell(true,true);Column&lt;C, Boolean&gt; checkColumn = new Column&lt;C, Boolean&gt;,覆盖 getValue(C) 以返回 cellTable.isSelected(object)。 checkColumn.setFieldUpdater(new FieldUpdater(){ @Override public void update(int index, C object, Boolean value) { cellTable.setSelected(object, value); } });
    • 啊,我一直在将 (true, true) 传递给标题中的复选框,但忘记检查实际列中的复选框...抱歉,它现在正在工作,谢谢你!
    猜你喜欢
    • 2017-09-23
    • 2014-08-08
    • 2010-12-04
    • 1970-01-01
    • 2023-03-17
    • 2013-05-10
    • 1970-01-01
    • 2015-12-24
    • 1970-01-01
    相关资源
    最近更新 更多