0

我有一个使用 PrimeFaces<p:selectOneMenu>定义的复合组件:

<p:selectOneMenu id="inOut" onchange="inOutChanged()">
  ..
</p:selectOneMenu>

然后我有一个 JavaScript 文件,它作为定义 inOutChanged()函数的组件的一部分包含在内,例如

function inOutChanged() {
  var inOut = $({cc.clientId}:inOut);
  if(inOut.val() == "INC") {
    slider.addClass("includedInRange");
  }
}

当页面上只有一个时,此复合组件可以正常工作。问题是我需要在页面上有 4 个。因此,当我更改一个复合组件的选择时,它正在更改最后一个组件的滑块类。我相信这是因为实际上inOutChanged()页面中定义了 4 个函数。

有没有办法确定函数的范围或唯一地命名它,这样它们就不会互相踩踏?

4

2 回答 2

2

您的具体问题是因为您slider在全局范围内重新声明并重新分配了相同的 JavaScript 变量。您需要将声明移动slider到函数内部。

重新声明完全相同的函数并没有什么害处,但效率低下而且不是DRY。您应该将该函数移动到它自己的.js文件中并使用<h:outputScript>它来包含它。JSF 最终只会将它包含一次。然后,相应地更改函数以将变量作为参数。

像这样的东西

<h:outputScript library="composite" name="some.js" target="head" />
...
<h:panelGroup id="...">
    <p:selectOneMenu ... onchange="inOutChanged(this)">
        ...
    </p:selectOneMenu>
    ...
    <p:slider ... />
</h:panelGroup>

里面有这个/resources/composite/some.js(前提是/resoruces/composite包含你的复合组件 XHTML 文件)

function inOutChanged(menuElement) {
    var $menu = $(menuElement);
    if ($menu.val() == "INC") {
        $menu.parent().find(".ui-slider").addClass("includedInRange");
    }
}
于 2013-04-05T12:05:21.253 回答
1

您应该$(this)在更改事件侦听器中使用选择器:

$(".inOut").change(function(){
    var sel = $(this).find('option:selected').text();
    if(sel == 'INC') {
        //find slider and add class
    }
});

请注意,我在组件范围之外绑定了 onchange 事件侦听器,并根据附加的 CSS 类找到了组件。这可以在$(document).ready().

当然,您可以在 JS 函数中使用客户端 ID,也可以将该函数绑定到组件的属性。

于 2013-04-05T05:09:53.267 回答