2013-04-05 3 views
0

У меня есть составной компонент, который использует PrimeFaces <p:selectOneMenu> определенные как:Когда составной компонент, содержащий JS код визуализируется несколько раз, JS работает только на последнем компоненте

<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 из них на странице. Поэтому, когда я меняю выбор одного составного компонента, он меняет класс ползунка последнего компонента. Я считаю, что это связано с тем, что есть функции 4 inOutChanged(), которые определены на странице.

Есть ли способ ограничить функцию или назвать ее уникально, чтобы они не топтались друг на друга?

+0

Вы искажая эту проблему. Во-первых, как и где вы указали переменную 'slider'? Это похоже на то, что вы только что переопределили значение переменной каждый раз, чтобы в конечном итоге удерживать последнее присвоенное значение. Все, у меня сложилось впечатление, что вы на самом деле означали «составной компонент», когда вы сказали «компонент»? Таким образом, вопрос будет иметь гораздо больше смысла. – BalusC

+0

@BalusC Да, это композитный компонент. Переменная ползунка также объявляется с использованием подхода similair с cc.clientId. Возможно, что я переопределил переменную ползунка. Я думаю, мне придется попробовать подход, который вы предложили в своем ответе, может быть, тоже. – mpaulse

ответ

2

Ваша конкретная проблема вызвана тем, что вы переопределили и переназначили одну и ту же переменную JavaScript slider в глобальной области. Вам нужно переместить объявление slider внутрь функции.

Redeclaring точно такая же функция не наносит вреда, но является простой неэффективной, а не 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"); 
    } 
} 
+0

Это не из-за моей переменной ползунка. Это было объявлено в моей функции, поэтому оно должно было быть уникальным. Тем не менее, я использовал как ваш подход к созданию отдельной функции, которая была включена, так и с использованием этого + родительского селектора.Мне пришлось возиться с родительским селектором, поскольку PrimeFaces добавляет несколько слоев divs между группой Panel и selectOneMenu. Но это заставило меня двигаться вперед. – mpaulse

+0

Вы также можете использовать '.closest()' для получения ближайшего родителя, соответствующего данному селектору. – BalusC

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-функции или связывать эту функцию с атрибутом компонента.

+0

Я сделал подобный подход. Но ответ BalusC был более полезным. – mpaulse

+0

Это хорошо. Я рад, что мы могли бы помочь! – skuntsel