2011-01-05 3 views
3

Мы используем facelets для создания пользовательских компонентов ajaxy. Одним из способов, которые мы хотели бы имитировать из компонентов по умолчанию, является то, что идентификатор является необязательным, а идентификатор генерируется, если он не передан. Я могу уже сделать это следующим образом:Автогенерируемые идентификаторы для компонентов facelets

<ui:composition ...> 
    <div class="myComponent" id="#{jsfSupport.generateId(id)}"> 
    ... 
    </div> 
</ui:composition> 

Я использую JBoss эль вызвать метод поддержки (можно использовать функции эль-а):

public class JsfSupport { 

    public String generateId(String id) { 

    if (id==null || "".equals(id){ 
    return FacesContext.getCurrentInstance().getViewRoot().createUniqueId(); 
    } 
    return id; 
    } 

} 

Проблема заключается в том, что, если мне нужно что идентификатор где-то в моем javascript-коде в компоненте, мне нужно получить его снова. Поэтому я подумал, что могу сделать следующее:

<ui:composition ...> 
    <c:set var="id" value="#{jsfSupport.generateId(id)}" /> 
    <div class="myComponent" id="#{id}"> 
    ... 
    </div> 
    <script type="text/javascript"> 
    document.getElementById('#{id}'); 
    </script> 
</ui:composition> 

Но это не работает. Идентификатор все равно регенерируется, и я получаю два разных. Любые идеи относительно того, что было бы идеальным способом сделать это?

+0

Могу ли я спросить вас о том, как вы сможете получить доступ, что созданный «идентификатор» из страницу, где вы включили/использовали вышеуказанные компоненты ajax? Для примера: если вам нужно повторно создать пользовательский компонент ajax, как вы это сделаете? – bchetty

+1

@bchetty Вы не можете. Если вам нужно переписать его, вам нужно передать идентификатор. Автогенерированный идентификатор только в том случае, если нет внешнего взаимодействия с компонентом. –

+0

Спасибо за быстрый ответ! :) – bchetty

ответ

1

<c:set> in Facelets означает наложение псевдонимов, а не назначение как в JSP. Поэтому каждое использование #{id} переведено в отдельный звонок на #{jsfSupport.generateId(id)}, что приводит к проблемам, которые вы описываете.

Вы можете написать свой собственный вариант <c:set> тега, который будет оценивать пройденное выражение только один раз, и сохранить возвращаемое значение:

public class SetOnceHandler extends TagHandler 
{ 
    private TagAttribute var; 
    private TagAttribute value; 

    public SetOnceHandler(TagConfig cfg) 
    { 
     super(cfg); 
     value = getRequiredAttribute("value"); 
     var = getRequiredAttribute("var"); 
    } 

    public void apply(FaceletContext ctx, UIComponent parent) 
    { 
     ctx.setAttribute(var.getValue(ctx), value.getObject(ctx)); 
    } 
} 
+0

Это работает отлично! Благодарю. Я удивлен, что нет ничего особенного в этом ... –

+0

Я тоже сталкиваюсь с той же проблемой. Не могли бы вы объяснить, что нужно сделать, чтобы иметь этот обработчик? –

Смежные вопросы