在应用请求值阶段,执行组件树decode()
中所有实例的方法。UIComponent
这是检查和收集必要的 HTTP 请求参数的地方。在UIInput
组件(<h:inputText>
和朋友)的情况下,获取提交的值。如果是UICommand
组件(<h:commandButton>
和朋友),ActionEvent
则已排队。
万一<p:commandButton>
发生了神奇的事情,在下面提取了源代码CommandButtonRenderer#decode()
的相关部分(行号来自 PrimeFaces 3.5):
34 public void decode(FacesContext context, UIComponent component) {
35 CommandButton button = (CommandButton) component;
36 if(button.isDisabled()) {
37 return;
38 }
39
40 String param = component.getClientId(context);
41 if(context.getExternalContext().getRequestParameterMap().containsKey(param)) {
42 component.queueEvent(new ActionEvent(component));
43 }
44 }
如果您熟悉基本的 HTML,您应该已经知道name=value
每个输入元素的对和仅封闭表单的按下按钮作为请求参数发送到服务器。PrimeFaces 命令按钮基本上生成以下 HTML,
<button type="submit" name="formId:buttonId" ... />
从哪里formId:buttonId
打印UIComponent#getClientId()
。正是这个值被用作 HTTP 请求参数名称(HTTP 请求参数值是按钮的标签,但这里不再相关)。如果您熟悉JSF 在其之上运行的基本 Servlets,那么您也应该已经知道请求参数可以通过 获得HttpServletRequest#getParameter()
,包括name=value
按钮对。这允许区分按下的按钮。
正如你在上面的decode()
方法中看到的,这个UIComponent#getClientId()
值也被用来检查 HTTP 请求参数映射是否包含参数名称。如果是这样,那么 anActionEvent
将被排队,最终在调用应用程序阶段被调用。
至于 EL 论点,它实际上不是火箭科学。整个 EL 表达式只是在调用应用程序阶段执行。它不是在生成表单的 HTML 输出期间执行的,然后以某种方式作为请求参数传递。不,它只是在实际调用应用程序阶段执行的。