0

我有一个重复控件,它在特定视图中显示文档。对于每个文档(数据行),用户可以在线编辑和保存这些项目。我有一个额外的按钮,它将单个文档标记为默认值,这仅在编辑模式下可见,在将当前文档标记为默认值之前,它会遍历所有其他文档并将它们取消标记为默认值。此标记为默认值第一次有效,但是当我再次尝试(第二次)时,它会产生复制冲突。

编辑按钮只是将模式更改为编辑模式。

保存执行以下操作(部分刷新):

<xp:this.action>
    <xp:actionGroup>
        <xp:saveDocument var="deliveryDocument"></xp:saveDocument>
        <xp:changeDocumentMode mode="readOnly"
            var="deliveryDocument">
        </xp:changeDocumentMode>
    </xp:actionGroup>
</xp:this.action>

设置默认值执行以下操作(完全刷新):

<xp:this.action>
    <xp:actionGroup>
        <xp:executeScript
            script="#{javascript:markAsDefault(deliveryDocument);}">

        </xp:executeScript>
        <xp:saveDocument var="deliveryDocument"></xp:saveDocument>
        <xp:changeDocumentMode mode="readOnly"
            var="deliveryDocument">
        </xp:changeDocumentMode>
    </xp:actionGroup>
</xp:this.action>

markAsDefault 首先遍历所有现有的交付文档并将 isDefault 设置为空白(当前文档除外),然后为当前文档设置 isDefault 值(它不保存后端文档并且循环执行 doc.recycle ())。

任何帮助,将不胜感激。

更新:

function markAsDefault(deliveryDoc) {
    try {
        var db:NotesDatabase = deliveryDoc.getParentDatabase();
        var vwDeliveryAddress:NotesView = db.getView("viewName");

        var dc:NotesDocumentCollection = vwDeliveryAddress.getAllDocumentsByKey(deliveryDoc.getItemValueString("fldID"), true);

        var strUniversalID:String;

        strUniversalID = deliveryDoc.getDocument().getUniversalID();

        if (dc.getCount() > 0) {
            var doc:NotesDocument = dc.getFirstDocument()
            var nextDoc:NotesDocument;

            // mark all other docs as not default
            while (doc != null) {
                nextDoc = dc.getNextDocument();

                if (doc.getUniversalID() != strUniversalID) {
                    doc.replaceItemValue("isDefault", "");
                    doc.save();

                    doc.recycle();
                }

                doc = nextDoc;
            }
        }

        deliveryDoc.replaceItemValue("isDefault", "Yes");
    } catch (e) {
        log.logError(e.toString(), SEVERITY_HIGH, e.toString(), null, "website.nsf", "markAsDefault()", null, null);
    }
}
4

1 回答 1

2

我认为保存冲突的原因是因为您正在处理内存中(在 XPage 上)和磁盘上的相同文档。内存文档的时间戳是在磁盘文档保存之前,因此当您保存内存文档时会发生保存冲突。

如果您不介意在没有冲突的情况下相互覆盖,您可以在表单中设置一个属性以防止保存冲突。在表单属性中,在第一个选项卡上:冲突处理 - 不要创建冲突

在不设置属性的情况下解决此问题的最简单方法是一次仅可编辑一个文档。有一个包含当前可编辑文档的 unid 的 viewScope 变量。设置基于此属性呈现的表单。将字段绑定到 requestScope,使用文档中的默认值。当用户单击保存时,通过 unid/update 从 requestScope 值中查找文档。这样,您只需处理磁盘上的文档。

编辑 - 示例代码:

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
    <xp:this.data>
        <xp:dominoView var="peopleView" viewName="People"></xp:dominoView>
    </xp:this.data>
    <xp:table id="peopleTable">
        <xp:repeat id="peopleRepeat" rows="30" value="#{peopleView}" var="personRow">
            <xp:panel rendered="#{javascript:return ( viewScope.editableUnid === personRow.getUniversalID() );}"
                tagName="tr">
                <td>
                    <xp:inputText value="#{requestScope.firstName}" defaultValue="#{personRow.first_name}" />
                </td>
                <td>
                    <xp:inputText value="#{requestScope.lastName}" defaultValue="#{personRow.last_name}" />
                </td>
                <td>
                    <xp:button id="saveButton" value="Save">
                        <xp:eventHandler event="onclick" submit="true" refreshMode="partial" refreshId="peopleTable">
                            <xp:this.action><![CDATA[#{javascript:var doc = database.getDocumentByUNID( viewScope.editableUnid );
doc.replaceItemValue( 'first_name', requestScope.firstName );
doc.replaceItemValue( 'last_name', requestScope.lastName );
doc.save();
viewScope.editableUnid = null;}]]></xp:this.action>
                        </xp:eventHandler>
                    </xp:button>
                    <xp:button id="cancelButton" value="Cancel">
                        <xp:eventHandler event="onclick" submit="true" refreshMode="partial" refreshId="peopleTable">
                            <xp:this.action><![CDATA[#{javascript:viewScope.editableUnid = null;}]]></xp:this.action>
                        </xp:eventHandler>
                    </xp:button>
                </td>
            </xp:panel>
            <xp:panel rendered="#{javascript:return ( viewScope.editableUnid != personRow.getUniversalID() );}" tagName="tr">
                <td>
                    <xp:text value="#{personRow.first_name}" />
                </td>
                <td>
                    <xp:text value="#{personRow.last_name}" />
                </td>
                <td>
                    <xp:button id="editButton" value="Edit">
                        <xp:eventHandler event="onclick" submit="true" refreshMode="partial" refreshId="peopleTable">
                            <xp:this.action><![CDATA[#{javascript:viewScope.editableUnid = personRow.getUniversalID();}]]></xp:this.action>
                        </xp:eventHandler>
                    </xp:button>
                </td>
            </xp:panel>
        </xp:repeat>
    </xp:table>
</xp:view>
于 2012-08-31T05:36:21.260 回答