【问题标题】:xpages custom deleting doc. from view panelxpages 自定义删除文档。从视图面板
【发布时间】:2014-08-14 16:20:07
【问题描述】:

我正在尝试从viewPanel1 中删除选定的文档。该视图已分类(可以是 > 1 个类别)并列出来自 2 个不同数据源的文档,例如:CdocPdoc。这些文档。由一个公共字段链接。

我的场景:如果用户选择 Cdoc => 删除操作将发生在相应的 Cdoc 以及所有 Pdoc 属于同一类别中。如果用户选择Pdoc => 仅删除Pdoc。另外,我想添加一些确认文本,其中包含所选文档中的一些信息(值字段)。

我尝试了以下

    var viewPanel=getComponent("viewPanel1");
var docIDArray=viewPanel.getSelectedIds(); 
for(i=0;i < docIDArray.length;i++){

    var docId=docIDArray[i];
    var doc=database.getDocumentByID(docId);
    var formName = (doc == null)? null : doc.getItemValueString("Form");


if( formName =="fmPersContact" ){
     .....
   } // in this case, it works OK.

else if ( formName =="fmCompanie" ){ // here if I selected > 1 Cdoc, it deletes just one Cdoc + the respective PDocs.

var doc:NotesDocument = null;
doc=database.getDocumentByID(docId);
var ky:java.util.Vector = new java.util.Vector();
ky.add(doc.getItemValueString("txt_NumeCompanie"));

... // 删除方法 }

你能告诉我我做错了什么以及我在上面的代码中遗漏了什么吗?感谢您的宝贵时间!

【问题讨论】:

  • 我不确定我是否得到了确切的问题。似乎有点模糊。我的建议是不要使用视图控件。使用重复控件。有了它,您将获得更多的功能和灵活性。
  • 我已经问过这个问题几次了,但是您对删除过程的哪个部分有疑问?是否比较表单名称以查看需要什么样的删除过程?是否循环删除?这个问题太模糊了,任何人都无法真正帮助你。
  • 至于确认消息,我知道可以通过 CSJS 来完成,但我在自己最近的应用程序中对此的快速而肮脏的回应是创建自己的服务器端确认对话框。计算文本以查看用户是否选择了 1 个且仅 1 个文档,如果没有,则该文本是错误消息并且 ok 按钮被隐藏,否则显示正确的文本。确定按钮事件是删除功能。这是否是最佳实践,我不能说,因此我不会把它放在答案中。 ——我在努力帮助你,而不是伤害或攻击你。我们无法回答含糊的问题。
  • 我看到了一些东西。 1.从一个类别中获取所有文档时,不需要使用向量。其余的都不好回答
  • 你没有吞下异常,是吗?你在检查你的例行程序是否扔了任何东西吗?

标签: xpages xpages-ssjs


【解决方案1】:

您要做的第一件事是确认。与 Lotusscript 不同,您不能在脚本中间使用函数来打开确认对话框并获得答案。为此,我建议在执行脚本简单操作之前使用确认简单操作。

<xp:button
        value="delete"
        id="button1"
    >
    <xp:eventHandler event="onclick" submit="true" refreshMode="complete">
        <xp:this.action>
            <xp:actionGroup>
                <xp:confirm message="Are you certain?"></xp:confirm>
                <xp:executeScript
                    script="#{javascript:doSomething();}"
                >
                </xp:executeScript>
            </xp:actionGroup>
        </xp:this.action></xp:eventHandler></xp:button>

编辑
过去,我还使用扩展库构建了自己的对话框,用 SSJS 填充文本,然后从对话框本身调用 doWhatever() 或 close()。这不是最好的解决方案,因为它需要从服务器更新才能获取字符串。正如 Paul Withers 所说,最好的解决方案是使用 CSJS 来执行确认。不过我还没有这样做。
/EDIT

对于您的删除功能,我建议获取您要删除的文档,然后通过表单名称或您使用的任何机制判断它是 P- 还是 C- doc,然后删除单个文档或通过使用 getAllDocumentsBykey() 从视图中获取文档集合,然后遍历它们,一一删除。

var ky:java.util.Vector = new java.util.Vector();
ky.add("MainCat");
ky.add("subCat");
ky.add("subCat2");
var vw:NotesView = database.getView("vw_myView");
var docs:NotesDocumentCollection = vw.getAllDocumentsByKey(ky);
//... delete stuff...
//dont forget to recycle

发布问题编辑
我建议使用以下方法来获取表单名称:

    var getSelectedDoc = function(){
        var vwPnl = getComponent("viewpanel");
        var ids = vwPnl.getSelectedIds();
        var id = null;
        var doc:NotesDocument = null;
        if(ids.length > 0){ //could use for loop var i = 0; i < ids.length;i++
            id = ids[0]; //could pack all ids into java.util.ArrayList and return that list to work on further
//be warned that if the user selects a parent doc and those automatically deleted by it that you need a mechanism to check if the document was already deleted!
        }
        if(id != null){
            doc = database.getDocumentByID(id);
        }
        return doc;
    }

    var doc = getSelectedDoc();
    var formName = (doc == null)? null : doc.getItemValueString("form");
    if(PDOC_FORM_NAME.equalsIgnoreCase(formName)){
        deleteFunctionComplete(doc);
    } else if (CDOC_FORM_NAME.equalsIgnoreCase(formName)){
        deleteFunctionTwo(doc);
    } else {
       // uh-oh
    } 

这还允许您拥有该文档,以防您想立即删除它。

对 cme​​ts 的修改 如果 Cdoc 应该删除多个文档,那么可以。您应该使用 getAllDocumentsBykey 记住需要为它构建视图。我的意思是如果你有一个单一类别的视图,没有问题,只需插入字符串就可以了。如果您有一个包含三个类别的视图,则不能将向量输入到只有两个值的 getalldocs 函数中,它必须是全部三个。因此,如果视图如下所示,您想删除所有“mycomp”以及底层 pdocs "Greg" "Sally "Bob",只需使用 alldocsbykey("mycomp"):

mycomp
---格雷格
---莎莉
---鲍勃

但如果视图看起来像

波兰
---mycomp
------格雷格
------莎莉
------鲍勃

那么必须使用带有 poland 和 mycomp 的 a 向量。 “波兰”没有得到正确的文件。 -- 只是有时存在的一个仅供参考和陷阱。

在进一步澄清问题后进行编辑
我更喜欢这种循环样式来删除文档

 var doc_temp:NotesDocument = null;
var doc_toDelete:NotesDocument = null;
var coll_docs:NotesDocumentCollection = ...; //get document collection

var doc_nextDoc = coll_docs.getFirstDocument();
while(doc_nextDoc != null){
    doc_temp = doc_nextDoc; //set document to delete
    doc_nextDoc = coll_docs.getNextDocument(doc_nextDoc);  // set next document before deletion
    try{
        doc_temp.remove(true);//lots of errors can happen here, such as ACL settings
    } catch(e) {
    //handle, or just break
    } finally{
        if(doc_temp != null) try{doc_temp.recycle()} catch(e){}// try to recycle, could also cause errors
        doc_temp = null;// for the sense of completeness 
    }
}

根据问题编辑进一步编辑
当然,您只是删除了一个 Pdoc,按照您的设置方式,您只会返回一个文档。您可以扩展 getSelectedDoc() 以将所有选定的文档放入 java.util.ArrayList 或其他东西中,然后使用该数组列表一次删除多个,但这可能很危险,具体取决于您的操作,因为 NotesDocuments 不是可序列化的。在这种情况下,我建议使用与 getSelected doc 相同的代码,使用 for 循环获取文档 ID,获取文档,如果文档不为空,则删除。

apropos getAllDocumentsByKey(带有向量)

目前的设置方式,不需要 Vector。
如果您有一个包含类别和子类别的视图,并且您想要获取该子类别中的所有文档,那么您必须使用向量来获取它。如果包含一个简单的字符串或只有一个值的向量,则不会返回子类别中的文档。向量可以认为是“cat1”、“subcat”、“furtherSubCat”

此外,这里没有检查从文档返回的字符串是否为空。应该这样做。也没有检查 DocumentCollection 是否为空。这也应该这样做。我的预期是,基于上述原因检索集合时会出现问题。

【讨论】:

  • 请记住,您推送到确认提示的任何 SSJS 都必须在确认提示写入浏览器之前进行计算,因为它作为 CSJS 运行。因此,它不会考虑用户在写入浏览器的页面或页面部分与显示确认之间所做的任何更改。它将是最后一次呈现页面时的值。如果您想在页面最后呈现后使用用户更新的任何内容,您将需要使用客户端脚本区域,而不是简单的确认操作。
  • @Greg 感谢您的提示。我创建了第一个 if 案例(简单的案例......当文档是 PDoc 时),但是如果文档是 Cdoc,我会遇到一些麻烦。所以在这种情况下,我应该使用 getAllDocumentsByKey 方法并一个一个地浏览文档...?
  • 我的评论太长,我会编辑问题。还请在问题中包含您的错误处理代码,以便我查看“自动删除”问题。
  • 对不起,那是我的错误。目前我正在工作 * 感谢您的提示和帮助 * 在第二种情况下,当我选择 Cdoc => 我还必须删除所有具有相同键的 Pdocs... 是否可以将一些字段值连接到确认文本?比如:“嘿,您选择了一个名为 >bla bla
  • 有一种方法可以用 CSJS 来做(我在那里帮不上忙),但我通常用 SSJS 来做,根据我对这个问题的评论,它具有比简单的功能和目的更多的功能和目的确认对话框。该字符串被计算并放入一个 scopedVariable 中,然后呈现给用户,我还执行检查以确保满足某些条件并在同一个确认对话框中向用户呈现任何问题。也许不是最好的情况,但它对我有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多