【问题标题】:GWT ListEditor implementing HasEditorErrors, custom error marking for ListEditorGWT ListEditor 实现 HasEditorErrors,ListEditor 的自定义错误标记
【发布时间】:2012-07-21 19:29:51
【问题描述】:

我有这个 ListEditor 负责为客户编辑许可证。在我的CustomerEditor 中,LicensesEditor 绑定到路径许可证,其类型为List<License>>

客户 (1)--> (许多) 许可证 (java.util.List)

现在,验证规则规定每位客户至少需要一份许可。约束违规工作完美。但是如何为 ListEditor 实现 HasEditorErrors ...我想提供自己的错误标记。

我为 HasEditorErrors 的泛型参数 T 注入什么类型??

public interface HasEditorErrors<T> extends Editor<T>

ListEditor 的签名如下...

public class LicensesEditor extends Composite implements IsEditor<ListEditor<License, LicenseInListEditor>>

我尝试实现HasEditorErrors&lt;List&lt;License&gt;&gt;,它在运行时给出错误:

[DEBUG] [klawtapp] - 降级为许可证 [错误] [klawtapp] - 在代理类型 java.util.List 中找不到路径编辑器的 getter

如果我实现HasEditorErrors&lt;LicensesEditor&gt;

[错误] [klawtapp] 在代理中找不到路径编辑器的吸气剂 输入 com.klawt.screen.ui.customers.LicensesEditor

在 HasEditorErrors 中保留问号作为实现的接口会导致编译时错误:

LicensesEditor 类型不能扩展或实现 HasEditorErrors。 超类型不能指定任何通配符 LicensesEditor.java

有人吗?

更新,完整代码如下:

public class LicensesEditor extends Composite implements IsEditor<ListEditor<License, LicenseInListEditor>> {

    @UiField
    Image validationErrorIcon;

    interface LicensesEditorUiBinder extends UiBinder<Widget, LicensesEditor> {
    }

    private static LicensesEditorUiBinder uiBinder = GWT.create(LicensesEditorUiBinder.class);

    @UiField
    VerticalPanel container;

    ListEditor<License, LicenseInListEditor> editor;

    public LicensesEditor() {
        initWidget(uiBinder.createAndBindUi(this));
        editor = ListEditor.of(new LicenseInListEditorSource());
        clearErrors();
    }

    @Override
    public ListEditor<License, LicenseInListEditor> asEditor() {
        return editor;
    }

    public void addLicense(License emailAddress) {
        editor.getList().add(emailAddress);
        if (emailAddress.getAdministrator()) {
            setPrimary(editor.getList().size() - 1);
        }
    }

    public void remove(int index) {
        editor.getList().remove(index);
    }

    public void update(int index, License emailAddress) {
        editor.getList().remove(index);
        editor.getList().add(index, emailAddress);
    }

    /**
     * make the phonenumber at the index the primary phonenumber and the other
     * phone numbers not primary.
     * 
     * @param index
     */
    public void setPrimary(int index) {
        int loop = 0;

        for (License emailAddress : Collections.unmodifiableList(editor.getList())) {
            emailAddress.setAdministrator(index == loop);
            update(loop, emailAddress);
            loop++;
        }
    }

    private class LicenseInListEditorSource extends EditorSource<LicenseInListEditor> {

        @Override
        public LicenseInListEditor create(final int index) {
            LicenseInListEditor editor = new LicenseInListEditor();
            editor.addDeleteHandler(new ListEditorDeleteEventHandler() {
                @Override
                public void onEditorEvent(ListEditorDeleteEvent event) {
                    remove(index);
                }
            });
            editor.addUpdateHandler(new EditorUpdateEventHandler() {
                @Override
                public void onEditorUpdate(EditorUpdateEvent event) {
                    License emailAddress = (License) event.getUpdated();
                    update(index, emailAddress);
                    if (emailAddress.getAdministrator()) {
                        setPrimary(index);
                    }
                }
            });
            container.insert(editor, index);
            updateOddEven();
            return editor;
        }

        @Override
        public void dispose(LicenseInListEditor subEditor) {
            container.remove(subEditor);
            updateOddEven();
        }

        @Override
        public void setIndex(LicenseInListEditor editor, int index) {
            container.insert(editor, index);
            updateOddEven();
        }

        public void updateOddEven() {
            for (int widgetIndex = 0; widgetIndex < container.getWidgetCount(); widgetIndex++) {
                container.getWidget(widgetIndex).setStyleName(KlawtResources.INSTANCE.form().listEditorEven(),
                        (widgetIndex % 2 == 0));
                container.getWidget(widgetIndex).setStyleName(KlawtResources.INSTANCE.form().listEditorOdd(),
                        (widgetIndex % 2 == 1));
            }
        }

    }

    // @Override
    // public void showErrors(List<EditorError> errors) {
    // StringBuilder sb = new StringBuilder();
    // int errorCount = 0;
    // for (EditorError editorError : errors) {
    // if (errorCount > 0) {
    // sb.append("\n");
    // }
    // errorCount++;
    // sb.append(editorError.getMessage());
    // }
    // if (errorCount == 0) {
    // clearErrors();
    // } else {
    // container.setStyleName(KlawtResources.INSTANCE.form().formError(), true);
    // validationErrorIcon.setVisible(true);
    // validationErrorIcon.setTitle(sb.toString());
    // }
    // }

    private void clearErrors() {
        container.setStyleName(KlawtResources.INSTANCE.form().formError(), false);
        validationErrorIcon.setVisible(false);
        validationErrorIcon.setTitle("");
    }

}

【问题讨论】:

  • 这是因为它是一个列表接口,我需要一个像 ArrayList 这样的实现吗?

标签: validation gwt bean-validation


【解决方案1】:

T 不是问题,混合和匹配 EditorIsEditor 是与(我怀疑 - 没有发布超过类型 decls 很难说)LicensesEditor 的一些内部(即,ListEditor 成员的访问修饰符,我想你称之为editor)。

IsEditor&lt;E&gt; 接口用于表示“我自己不是编辑器,但我可以提供一个”,其实现Editor 的非私有成员将被忽略,但框架仍将下降到E 中的非私人编辑。因为(我怀疑)你的 LicensesEditor 内部实际上有一个非私人编辑成员,

那么这会给你带来什么影响?几个对我来说似乎有意义的选择:

  • 停止使用IsEditor,这样你就可以实现HasEditorErrors。相反,制作LicensesEditor extends Composite implements Editor&lt;List&lt;Licenses&gt;&gt;, HasEditorErrors&lt;List&lt;Licenses&gt;&gt;(虽然技术上第一个Editor 被第二个覆盖,但我发现它有助于提高可读性)。现在您仍然需要一个 ListEditor 成员(几乎可以肯定您目前已经拥有),但使用 @Path("") 对其进行注释以表明它应该编辑整个编辑器获得的相同值。

  • 使用IsEditor,但使其在HasEditorErrorsListEditor 上都通用——创建一个同样实现HasEditorErrors 并具有错误支持的ListEditor 子类。这使您仍然可以在包装类中扩展Composite。把这个转过来,你就有了……

  • 扩展 ListEditor,并实现 IsWidget 而不是扩展 Composite。这实现了与第一个选项相同的效果(您可以通过摆脱 IsEditor 使 LicensesEditor 实现 HasEditorErrors),而无需使用 @Path 使事情变得有意义。现在,不要调用Composite.initWidget,而是保留对小部件的引用,并将其返回给IsWidget.asWidget()

  • 最后,什么都不做。来自IsEditorJavadocs:

    一个类型同时实现 Editor 和 IsEditor 是合法的。在这种情况下, 从 {@link #asEditor()} 返回的编辑器将是 IsEditor 实例。

    这意味着LicensesEditor 应该是一个有效的Editor - any non-private Editor member should either be changed to private or tagged with@Ignore`。

【讨论】:

  • 这需要一些测试...我会报告我的发现。
  • 你说得对,我有一个内部编辑器。我从您的回答中选择了选项 1,将 sig 更改为 public class LicensesEditor extends Composite implements Editor>, HasEditorErrors> 并将 @Editor.Path("") 添加到内部编辑器...和成功:)谢谢你的好答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多