0

特定のビューでドキュメントを表示する繰り返しコントロールがあります。ドキュメント (データの行) ごとに、ユーザーはこれらのアイテムをインラインで編集および保存できます。単一のドキュメントをデフォルトとしてマークする追加のボタンがあり、これは編集モードでのみ表示されます。現在のドキュメントをデフォルトとしてマークする前に、他のすべてのドキュメントを調べてデフォルトからマークを外します。このデフォルトのマークは最初は機能しますが、もう一度試すと (2 回目)、レプリケーションの競合が発生します。

編集ボタンは、モードを編集モードに変更するだけです。

保存は次のことを行います (部分的な更新)。

<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 上) とディスク上で同じドキュメントを扱っているためだと思います。メモリ内ドキュメントのタイム スタンプはディスク上のドキュメントが保存される前であるため、メモリ内ドキュメントを保存すると保存の競合が発生します。

競合せずに互いに上書きしても構わない場合は、保存の競合を防ぐ形式でプロパティを設定できます。フォーム プロパティの最初のタブ:競合処理 - 競合を作成しない

プロパティを設定せずにこの問題を回避する最も簡単な方法は、一度に 1 つのドキュメントのみを編集可能にすることです。現在編集可能なドキュメントの 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 に答える