值选择器获取错误TypeError:resp在XPages中为null

值选择器获取错误TypeError:resp在XPages中为null,xpages,xpages-extlib,Xpages,Xpages Extlib,我不知道哪里出了问题,我在另一个页面上有几乎完全相同的代码。我让valuePicker从viewScope.vsFieldNames中获取其值,我知道在单击值选择器之前已填充该值,但当选择器对话框显示时,我得到错误信息 TypeError:resp为空 字段reqOnSave是一个多行编辑框,它为空,但我认为这不会有任何区别。我在其他几页中使用了范围变量作为值列表,没有遇到任何问题。我肯定我错过了一些简单的东西 10月17日编辑 我的页面如下所示: 当我点击选择字段时,我会看到下面的显示。我知

我不知道哪里出了问题,我在另一个页面上有几乎完全相同的代码。我让valuePicker从viewScope.vsFieldNames中获取其值,我知道在单击值选择器之前已填充该值,但当选择器对话框显示时,我得到错误信息

TypeError:resp为空

字段reqOnSave是一个多行编辑框,它为空,但我认为这不会有任何区别。我在其他几页中使用了范围变量作为值列表,没有遇到任何问题。我肯定我错过了一些简单的东西

10月17日编辑 我的页面如下所示:

当我点击选择字段时,我会看到下面的显示。我知道此时已正确填充viewScope.vsFieldNames,因为我使用调试工具栏对其进行了检查

我真的不喜欢xe:valuePicker,因为它调用一个对话框,我更喜欢多选组合框,但没有一个标准的核心或扩展库控件来实现这一点(至少我可以找到)

这是我的完整代码:

   <div class="row">
        <div class="col-sm-2">
            <xp:label value="Application" id="label1"
                for="ApplicationCombo">
            </xp:label>
        </div>
        <div class="col-sm-4">
            <xp:comboBox id="ApplicationCombo"
                value="#{formDoc.Application}">
                <xp:selectItems>
                    <xp:this.value><![CDATA[#{javascript:var rtn:Array = database.getView("vwWFSApplicationsEnabled").getColumnValues(0);
rtn.unshift("");}]]></xp:this.value>
                </xp:selectItems>
                <xp:eventHandler event="onchange" submit="true"
                    refreshMode="partial" refreshId="panelBody">
                    <xp:this.action>
                        <![CDATA[#{javascript:try{formDoc.replaceItemValue("FormName","");
}catch(e){

}}]]>
                    </xp:this.action>
                </xp:eventHandler>
            </xp:comboBox>
        </div>
    </div>
    <xp:panel id="panelBody">
    <xp:text escape="true" id="computedField1">
        <xp:this.value><![CDATA[#{javascript:try{
    var app:string = formDoc.getValue("Application");
    var debug:Boolean = true;
    if (debug) WFSUtils.sysOut("Application = " + app);
    var form:String = formDoc.getValue("FormName");
    if (debug) WFSUtils.sysOut("Form = " + form);
    if (!(app == null || app == "")){
        if ((!(form.substring(0,3) == "---")) && (!(form == null || form == ""))) {
            if (debug) WFSUtils.sysOut("Form Name = " + form);
            var thisForm:NotesForm = appProps[app].appDB.getForm(form);
            if (debug) WFSUtils.sysOut("Got Form Name = " + thisForm.getName());
            var rtn:Array = thisForm.getFields();
            if (debug) WFSUtils.sysOut("Rtn = " + rtn.toString());
            viewScope.vsFieldNames = rtn;
            return null
        }
    }
    viewScope.vsFieldNames = null;
    return null
}catch(e){

    WFSUtils.sysOut("Error in Get Fields " + e.toString());
    viewScope.vsFieldNames = null;
    return null;
}}]]></xp:this.value>
    </xp:text>
    <div class="row">
            <div class="col-sm-2">
                <xp:label value="Form Name :" id="label2"
                    for="FormCombo">
                </xp:label>
            </div>
            <div class="col-sm-4">
                <xp:comboBox id="comboBox1"
                    value="#{formDoc.FormName}">
                    <xp:selectItems>
                        <xp:this.value>
                            <![CDATA[#{javascript:var app:string = formDoc.getValue("Application");
if (!(app == null || app == "")){
    var rtn = appProps[app].appDB.getView("vwWFSForms").getColumnValues(0);
    rtn = sort_unique(rtn);
    rtn.unshift("--- Select A Form ---");
    return rtn
}else{
    return null
}}]]>
                        </xp:this.value>
                    </xp:selectItems>
                    <xp:eventHandler event="onchange" submit="true"
                        refreshMode="partial" refreshId="panelBody">
                    </xp:eventHandler>
                </xp:comboBox>
            </div>
        </div><!-- row Form -->
        <div class="row">
            <div class="col-sm-2">
                <xp:label value="Required Fields On Save :" id="label3"
                    for="djComboReqOnSave">
                </xp:label>
            </div>
            <div class="col-sm-4">
                <xe:valuePicker id="pickerFields"
                    dialogTitle="Select One or More Fields" for="reqOnSave"
                    pickerText="Select Field/s :">
                    <xe:this.dataProvider>
                        <xe:simpleValuePicker caseInsensitive="false">
                            <xe:this.valueList><![CDATA[${javascript:viewScope.vsFieldNames;
}]]></xe:this.valueList>
                        </xe:simpleValuePicker>
                    </xe:this.dataProvider>
                </xe:valuePicker>

            </div>
            <div class="col-sm-2">
                <xp:inputTextarea id="reqOnSave"
                    value="#{formDoc.ReqOnSave}" multipleSeparator=",">
                </xp:inputTextarea>
            </div>
        </div><!-- row reqOnSave -->
        <div class="row">

        </div>
    </xp:panel>

resp是传递给选择器的客户端JavaScript变量,因此选择器没有加载任何选项

ValuePicker使用
${javascript:viewScope.vsFieldNames;}
。因此,使用调试工具栏可以看到的事实可能会产生误导,因为调试工具栏在值加载到ValuePicker后显示输出

要使用该代码,您需要在
beforePageLoad
事件中设置
viewScope.vsFieldNames
。要在代码运行时再次检查它是否为null,请修改以在调用
viewScope.vsFieldNames
之前调试内容,例如
${javascript:print(viewScope.vsFieldNames);返回viewScope.vsFieldNames;}
。当它运行时,值可能还没有初始化


如果无法在beforePageLoad中设置它,则要解决此问题,请使用
{javascript:viewScope.vsFieldNames;}
(SSJS页面加载)而不是
{viewScope.vsFieldNames}
(EL dynamic)。这应该是可行的,您将避免使用SSJS解析器,这样性能就不会受到负面影响。

什么控件是“resp”?看起来好像在名为“panelBody”的容器中有什么东西试图在“panelBody”更新后对名为“resp”的控件或对象进行处理。你说这是在另一个页面中工作;这将是关键:有什么区别?我刚刚意识到:屏幕截图显示的东西看起来像一个警报(XPiNC?),但它的标题“TestError”有点特殊,看起来不像一个标准的系统警报,并且您的代码引用的是一个对象“WFSUtils”;也许你需要在那里寻找那个神秘的“resp”物体…不是你问题的答案,而是我感觉到的需要注意的东西。当我丢失会话时(如会话过期时),我总是用值选择器得到“resp is null”。Paul下面的回答修复了这个问题。Lothar WFSUtils.sysOut只是格式化一条消息,然后将其打印到服务器控制台。“TestError”是被调用的XPage的名称。VSFieldName中的值取决于应用程序和表单,因此它不能在beforePageLoad中,因此将尝试使用EL。