Автоматически сгенерированные идентификаторы для компонентов Facelets - PullRequest
3 голосов
/ 05 января 2011

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

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

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

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>

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

1 Ответ

1 голос
/ 05 января 2011

<c:set> в 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));
    }
}
...