Javascript 试图从CSJS在viewscope中设置BS accordian的状态,但值始终相同(且不正确)

Javascript 试图从CSJS在viewscope中设置BS accordian的状态,但值始终相同(且不正确),javascript,twitter-bootstrap,xpages,Javascript,Twitter Bootstrap,Xpages,在我的XPage上,我定义了一个BS手风琴: <div class="panel-collapse collapse in" id="collapseOne" aria-expanded="true" style=""> </div> 在一个按钮上,我想保存面板的状态,所以在完全刷新后,我想显示手风琴面板的前一个状态 因此,我的按钮现在看起来如下所示: <xp:button value="Label" id="button1"&

在我的XPage上,我定义了一个BS手风琴:

<div class="panel-collapse collapse in" id="collapseOne" aria-expanded="true" style="">
</div>

在一个按钮上,我想保存面板的状态,所以在完全刷新后,我想显示手风琴面板的前一个状态

因此,我的按钮现在看起来如下所示:

<xp:button
        value="Label"
        id="button1">
    <xp:eventHandler
        event="onclick"
        submit="true"
        refreshMode="complete">
        <xp:this.script><![CDATA[if ($('#collapseOne').attr('aria-expanded') == "false") {
"#{javascript:viewScope.put('accordian','collapsed')}";
}else{
"#{javascript:viewScope.put('accordian','expanded')}";
}]]></xp:this.script>
    </xp:eventHandler>
</xp:button>

无论手风琴处于何种状态,只要脚本识别出手风琴的正确状态,viewScope“手风琴”都将设置为“展开”

我做错了什么

<xe:jsonRpcService
                                id="rpcServiceSetState">
                            <xe:this.methods>
                                <xe:remoteMethod
                                    name="setPanelState"
                                    loaded="true"
                                    script="viewScope.put('accordian', state)">
                                    <xe:this.arguments>
                                        <xe:remoteMethodArg
                                            name="state"
                                            type="string">
                                        </xe:remoteMethodArg>
                                    </xe:this.arguments>
                                </xe:remoteMethod>
                            </xe:this.methods></xe:jsonRpcService>
                            <xp:button id="btnTriggerRPC" value="Trigger RPC Method">
        <xp:eventHandler
            event="onclick"
            submit="true" refreshMode="complete">
            <xp:this.script><![CDATA[if ($('#collapseOne').attr('aria-expanded') == "false") {
    rpcServiceSetState.setPanelState('collapsed')
}else{
    rpcServiceSetState.setPanelState('expanded')
}]]></xp:this.script>
        </xp:eventHandler>
                            </xp:button>
更新:

我按照建议设置了一个RPC服务,但它不起作用。我做错了什么

<xe:jsonRpcService
                                id="rpcServiceSetState">
                            <xe:this.methods>
                                <xe:remoteMethod
                                    name="setPanelState"
                                    loaded="true"
                                    script="viewScope.put('accordian', state)">
                                    <xe:this.arguments>
                                        <xe:remoteMethodArg
                                            name="state"
                                            type="string">
                                        </xe:remoteMethodArg>
                                    </xe:this.arguments>
                                </xe:remoteMethod>
                            </xe:this.methods></xe:jsonRpcService>
                            <xp:button id="btnTriggerRPC" value="Trigger RPC Method">
        <xp:eventHandler
            event="onclick"
            submit="true" refreshMode="complete">
            <xp:this.script><![CDATA[if ($('#collapseOne').attr('aria-expanded') == "false") {
    rpcServiceSetState.setPanelState('collapsed')
}else{
    rpcServiceSetState.setPanelState('expanded')
}]]></xp:this.script>
        </xp:eventHandler>
                            </xp:button>

如果您使用浏览器开发工具查看浏览器上的内容,您将看到问题的根源。SSJS只在服务器上运行,代码的结果被注入CSJS函数并传递给浏览器。CSJS仅在浏览器上运行,不能在服务器上运行

CSJS只是一个要传递给浏览器的字符串。查看PackageExplorer中的
local\xsp
文件夹,找到您的XPage。“if”语句不能在服务器上运行,只能在
{javascript:…}
中运行

Sven是对的,在页面加载和每次刷新时,您都会调用
viewScope.put()
将值设置为“折叠”和“展开”。之所以同时运行这两个语句,是因为SSJS中没有“if”语句

这可能有助于澄清这一点,我相信我已经在我的TLCC网络研讨会视频中介绍了这一点。您需要通过CSJS将某些内容传递到隐藏的输入字段,然后您可以访问SSJS中的隐藏输入,并使用它来管理手风琴的状态


基本上,您需要为自定义JavaScript小部件构建自己的状态管理,正如我在这里所述,XPages会自动为自己的小部件处理这些事情。

下面的代码允许我通过RPC服务设置viewscope

<xe:jsonRpcService id="jsonRpcServiceSelected"
        serviceName="rpcService" rendered="true">
        <xe:this.methods>
            <xe:remoteMethod name="setAccordion"
                script="viewScope.put('accordion', selected);">
                <xe:this.arguments>
                    <xe:remoteMethodArg name="selected" type="string" />
                </xe:this.arguments>
            </xe:remoteMethod>

        </xe:this.methods>
    </xe:jsonRpcService>
<xp:button id="btnTriggerRPC" value="Trigger RPC Method">
        <xp:eventHandler
            event="onclick"
            submit="true"
            refreshMode="complete">
            <xp:this.script><![CDATA[if ($('#collapseOne').attr('aria-expanded') == "false") {
rpcService.setAccordion('collapsed');

}else{

    rpcService.setAccordion('expanded');
}]]></xp:this.script>
        </xp:eventHandler>
</xp:button>


生成CSJS代码并发送到客户端时,始终会执行SSJS代码。这就是为什么accorbian总是设置为expanded。但是如果为if-else结构添加警报,它会检测状态并警报正确的状态吗?是否还有其他解决方法?if/else-块在浏览器中执行,这就是警报工作的原因。如果您想更新服务器端状态,您需要更新它,例如使用RPC调用。但是JSON RPC服务对此没有帮助,因为组件树没有得到更新。嗨,Sven,我用建议的RPC方法更新了我的问题,但我一定是做错了什么?嗨,Paul,我用建议的rpc方法更新了我的问题,但我一定是做错了什么?请参阅我对原始问题的评论。JSON RPC不更新viewScope。我认为它允许