【问题标题】:Cannot discard changes made in fields in TableFieldFactory无法丢弃在 TableFieldFactory 中的字段中所做的更改
【发布时间】:2013-09-23 07:32:59
【问题描述】:

我有一个简单的表格,其中我使用 IndexedContainer 作为数据源来呈现一些数据。 我希望我的用户能够编辑其中的一些数据,因此我使用 TableFieldFactory (DefaultFieldFactory) 来生成这些可编辑的列(属性)。

现在,如果用户处于编辑模式 (table.setEditable(true)) 并且一直在更改某些字段,他或她应该能够放弃这些更改 - 为此,我有一个“取消”按钮。这个“取消”按钮应该放弃自用户进入编辑模式然后 setEditable(false) 以来在 Table 生成的字段中所做的所有更改 - 现在一切都应该是调用 setEditable(true) 之前的方式。

这听起来并不难,直到我尝试实现它。

如果我正确理解 Table、Container 和 TableFieldFactory 的功能,会发生以下情况:

  1. 属性被添加到容器中
  2. Container设置为Table数据源
  3. 用户单击“编辑表”按钮 (table.setEditable(true))
  4. Table 调用 TableFieldFactory 的重写 createField() 方法
  5. createField() 方法创建可编辑字段
  6. 用户在编辑字段的同时容器也得到更新
  7. 用户点击“取消”按钮

问题:当我按下“取消”按钮时,我应该怎么做discard()?我不能做table.discard(),因为改变已经发生了。我不能做 container.discard() 因为,是的,Container 接口不继承该方法。我不能执行 field.discard(),因为我无法从 createField() 方法之外访问字段。

我尝试了 setBuffered、markAsDirty、refreshRowCache 和 setImmediate 的不同变体,但均未成功。

这是(希望是所有)相关代码:

表格、容器和“取消”按钮(大致):

table.setContainerDataSource(container);

Button cancel = new Button("Cancel", new Button.ClickListener() {
    private static final long serialVersionUID = 1L;

    @Override
    public void buttonClick(ClickEvent event) {
        // table.setImmediate(false); //tried variations of this
        // table.refreshRowCache(); //tried variations of this
        // table.markAsDirty(); //tried variations of this
        // table.setBuffered(true); //tried variations of this
        // table.discard(); //tried this, but here it's too late
        table.setEditable(false);
    }
});

TableFieldFactory:

table.setTableFieldFactory(new DefaultFieldFactory() {
    private static final long serialVersionUID = 1L;

    @Override
    public Field<?> createField(Container container, Object itemId, Object propertyId, com.vaadin.ui.Component uiContext) {

        TextField tField = (TextField) DefaultFieldFactory.get().createField(container, itemId, propertyId, uiContext);
        tField.setImmediate(true);

        if (propertyId.equals("Foo")) {
            // field.setImmediate(true); //tried variations of this
            // field.setBuffered(false); //tried variations of this
            return tField;
        }
        else {
            tField.setReadOnly(true);
        }
        return tField;
    }
});

【问题讨论】:

    标签: vaadin vaadin7


    【解决方案1】:

    通过跟踪工厂中创建的字段(并使这些字段缓冲),您可以根据需要提交/丢弃。

    我在this self-contained GitHub Gist 中创建了一个缓冲表编辑的简单示例。选择一行并单击编辑(或双击)。进行更改,然后单击 Save/Hit Enter 提交,或 Cancel/Escape 放弃。

    我故意让每次只能编辑一行,因为坦率地说,这是唯一对我有意义的事情。显然,这很容易改变。

    【讨论】:

    • 我用 attachListeners 跟着你的例子,它就像一个魅力!谢谢你,查尔斯!
    • 我试图弄清楚 attachListeners 是如何工作的,但我很难在 API 中找到任何好的材料,甚至在谷歌搜索时也很难找到。如果我理解正确,它会是这样的: 1. attach- 和 detachListeners 添加到字段 2. 当字段附加到表时,“连接器字段”(相当于引用?)被添加到字段列表中3. 在字段列表中的“字段引用”上调用 commit() 时,该字段将被提交(如果调用了丢弃,则丢弃该字段)如果您能确认这一点,我将非常感激!
    • 当组件附加到 DOM 或从 DOM 分离时,简单地调用附加/分离侦听器。组件/字段是一种连接器。所以 - 我只是在附加/分离字段时跟踪它们。提交/放弃按钮只是提交/放弃所有附加的字段。
    猜你喜欢
    • 2019-01-14
    • 2011-01-07
    • 2011-06-17
    • 2010-12-07
    • 1970-01-01
    • 2017-04-22
    • 2020-06-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多