何时以及如何在 JSF 中生成 clientID? [英] When and how is clientID generated in JSF?

查看:16
本文介绍了何时以及如何在 JSF 中生成 clientID?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了更深入地了解 JSF (2.x) 中的 clientID 生成,有人可以向我解释一下 JSF 是什么时候生成客户端 ID 的(生命周期阶段、构建时间还是渲染时间...)?

In order to more understand the clientID generation in JSF (2.x), could someone explain to me when exactely does JSF generates the client ID (which lifecycle phase, build time or render time ...)?

以及如何生成客户端 ID(如果提供/不提供组件 ID 而不是随机或使用特定逻辑...)?

And how the client ID will be generated (if providing /not providing component ID and not, randomly or using a specific logic...) ?

推荐答案

为了更深入地了解 JSF (2.x) 中的 clientID 生成,有人可以向我解释一下 JSF 何时生成客户端 ID(哪个生命周期阶段、构建时间或渲染时间...)?

它必须以 HTML 响应结束.因此它是在渲染响应期间生成的.如果您在 UIComponent#getClientId() 方法,然后您将在堆栈中进一步看到(在 Mojarra 的情况下)RenderResponsePhase#execute() 已被调用.当断点被命中时,这足以暗示生命周期中的当前阶段.

It has to end up in HTML response. It's thus generated during render response. If you put a debug breakpoint on UIComponent#getClientId() method, then you'll see further down in the stack that (in case of Mojarra) RenderResponsePhase#execute() has been invoked. This is sufficient hint about the current phase in the lifecycle when the breakpoint is hit.

以及如何生成客户端 ID(如果提供/不提供组件 ID 而不是随机或使用特定逻辑...)?

抽象UIComponent#getClientId()方法的具体实现可以在UIComponentBase#getClientId().其源代码可以在 grepcode 找到.它将如何生成仅在 它的javadoc:

The concrete implementation of the abstract UIComponent#getClientId() method can be found in UIComponentBase#getClientId(). Its source code can be found at grepcode. How it will be generated is just described in its javadoc:

public abstract String getClientId(FacesContext context)

返回此组件的客户端标识符,必要时生成一个.关联的Renderer,如果有的话,会被要求将clientId转换成适合传输给客户端的形式.

Return a client-side identifier for this component, generating one if necessary. The associated Renderer, if any, will be asked to convert the clientId to a form suitable for transmission to the client.

该方法的返回值在实例的整个生命周期内必须是相同的值,除非组件的id属性发生变化,或者组件被放置在一个NamingContainer 其客户端 ID 更改(例如, UIData).但是,即使在这些情况下,对该方法的连续调用也必须始终返回相同的值.实现必须遵循以下步骤来确定 clientId:

The return from this method must be the same value throughout the lifetime of the instance, unless the id property of the component is changed, or the component is placed in a NamingContainer whose client ID changes (for example, UIData). However, even in these cases, consecutive calls to this method must always return the same value. The implementation must follow these steps in determining the clientId:

在实现 NamingContainer 的视图层次结构中查找与该组件最近的祖先.对其调用 getContainerClientId() 并将结果保存为 parentId 局部变量.调用 getId() 并将结果保存为 myId 局部变量.如果 myIdnull,则调用 context.getViewRoot().createUniqueId() 并将结果分配给 myId.如果 parentIdnull,让 myId 等于 parentId +UINamingContainer.getSeparatorChar(javax.faces.context.FacesContext)+ myId.调用 Renderer.convertClientId(javax.faces.context.FacesContext, java.lang.String),传入myId,返回结果.

Find the closest ancestor to this component in the view hierarchy that implements NamingContainer. Call getContainerClientId() on it and save the result as the parentId local variable. Call getId() on this component and save the result as the myId local variable. If myId is null, call context.getViewRoot().createUniqueId() and assign the result to myId. If parentId is non-null, let myId equal parentId +UINamingContainer.getSeparatorChar(javax.faces.context.FacesContext)+ myId. Call Renderer.convertClientId(javax.faces.context.FacesContext, java.lang.String), passing myId, and return the result.

很清楚,是吗?最重要的部分可能是记住实现 NamingContainer 的组件,从而在它们的客户端 ID 前面加上.在标准的 JSF 2.x 中,至少是 code>、.如果您轻轻地给所有组件一个固定 ID,那么您还会在生成的 HTML 输出.

Pretty clear, is it? The most important part is perhaps memorizing components which implement NamingContainer and thus prepend their client ID. In standard JSF 2.x, that are at least <h:form>, <h:dataTable>, <ui:repeat>, <f:subview> and <cc:implementation>. If you gently give all components a fixed ID, then you'll also see that pattern back in the generated HTML output.

如果你不给这些组件一个固定的 ID,那么将使用 JSF 生成的 ID,它可以通过 UIViewRoot#createUniqueId()(如上面的 javadoc 摘录中已经暗示的那样).其 javadoc 说:

If you don't give those components a fixed ID, then instead the JSF-generated ID will be used which can be obtained via UIViewRoot#createUniqueId() (as already hinted in the above javadoc extract). Its javadoc says:

public String createUniqueId()

为组件生成标识符.标识符将带有前缀 UNIQUE_ID_PREFIX,并且在此 UIViewRoot 的非 NamingContainer 子子树中将是唯一的.

Generate an identifier for a component. The identifier will be prefixed with UNIQUE_ID_PREFIX, and will be unique within the non-NamingContainer child sub-trees of this UIViewRoot.

该前缀是 <代码>j_id.它没有明确说明实现应该如何生成它,因此所有实现者都可以自由地实现它.它们通常使用树中组件计数的递增索引.因此,第一个组件 UIViewRoot 可以获得 j_id1 的 ID.它的第一个孩子可以获得 j_id2 的 ID.等等.您可以通过在 UIViewRoot#createUniqueId() 方法甚至 UIComponentBase#setId() 方法.

That prefix is j_id. It isn't explicit on how the implementation should generate it, so all implementors are free to implement it. They usually use an incremented index of the component count in the tree. So, the first component, the UIViewRoot, could get an ID of j_id1. Its first child could get an ID of j_id2. Etcetera. You can track back the logic by putting a debug breakpoint on UIViewRoot#createUniqueId() method or even the UIComponentBase#setId() method.

这篇关于何时以及如何在 JSF 中生成 clientID?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆