2011-01-05 38 views
3

我们使用facelets创建一些自定义ajaxy组件。我们希望从默认组件中模拟的一种行为是,id是可选的,如果它没有通过,则会生成id。我已经可以做这样的:自动生成的facelets组件的ID

<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; 
    } 

} 

的问题是,如果我需要那个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> 

但这并不行。无论如何,id都会重新生成,并且我得到两个不同的。 任何想法是什么将是理想的方式来做到这一点?

+0

我能问你关于你将如何访问生成的“ID”,从页面,您在哪里包含/使用了上述ajax组件?对于例如:如果你必须reRender自定义ajax组件,你会怎么做? – bchetty 2012-09-05 12:40:53

+1

@bchetty你不能。如果你需要重新渲染它,你需要传入一个Id。只有在没有与组件进行外部交互的情况下,自动生成的ID才会生效。 – 2012-09-05 12:42:05

+0

感谢您的快速响应! :) – bchetty 2012-09-05 12:54:28

回答

1

<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)); 
    } 
} 
+0

这完美的作品!谢谢。我很惊讶,这是没有开箱即用的东西... – 2011-01-06 08:32:10

+0

我也面临完全相同的问题。你能解释一下为了让这个处理程序到位需要做什么吗? – 2013-01-04 08:11:45