【发布时间】:2011-11-23 12:34:39
【问题描述】:
我创建了一个自定义组件。我向它添加了一个动态输入文本框(来自编码函数)。
组件正确呈现为 HTML。
但我想将文本框的值绑定到托管 Bean 上的某个属性。所以其他一些开发人员可以在他的托管 bean 上使用他的 jsp 上的组件。
我想知道,我应该怎么做,以便将文本框中输入的值(我的组件动态创建)设置为某个托管 bean 属性。
【问题讨论】:
标签: jsf custom-component
我创建了一个自定义组件。我向它添加了一个动态输入文本框(来自编码函数)。
组件正确呈现为 HTML。
但我想将文本框的值绑定到托管 Bean 上的某个属性。所以其他一些开发人员可以在他的托管 bean 上使用他的 jsp 上的组件。
我想知道,我应该怎么做,以便将文本框中输入的值(我的组件动态创建)设置为某个托管 bean 属性。
【问题讨论】:
标签: jsf custom-component
好了,问题解决了。
在 encodeEnd() 方法中,我将元素添加为
HtmlInputHidden hidden = new HtmlInputHidden();
hidden.setParent(this);
hidden.setId("someId");
ValueExpression ve = getValueExpression("value");
hidden.setValueExpression("value", ve);
hidden.encodeBegin(context);
hidden.encodeEnd(context);
这似乎有些问题。
然后我将其更改为...
HtmlInputHidden hidden = new HtmlInputHidden();
hidden.setId("someId");
ValueExpression ve = getValueExpression("value");
hidden.setValueExpression("value", ve);
this.getChildren().add(hidden);
hidden.encodeBegin(context);
hidden.encodeEnd(context);
this.getChildren().add()的使用;解决了我的问题
附:显然在添加元素之前,需要检查元素是否已经存在。
【讨论】:
您需要确保您的自定义组件类扩展了UIInput,并且您在渲染器的encodeEnd() 方法中将组件的客户端ID 写入HTML 输入元素的name 属性。然后您可以在您的渲染器的覆盖decode() 方法中,只需从请求参数映射中以组件的客户端ID 作为参数名称获取提交的值,并将其设置为UIInput#setSubmittedValue() 并让JSF 完成剩余的转换工作,验证和更新模型值。
@Override
public void decode(FacesContext context, UIComponent component) {
// Do if necessary first validation on disabled="true" or readonly="true", if any.
// Then just get the submitted value by client ID as name.
String clientId = component.getClientId(context);
String submittedValue = context.getExternalContext().getRequestParameterMap().get(clientId);
((UIInput) component).setSubmittedValue(submittedValue);
}
与具体问题无关,您知道 JSP 的后续 Facelets 中新的复合组件支持吗?我的印象是,您不一定需要为此目的使用自定义组件。或者,尽管您已经使用 JSF 2.x,但您是否真的仅限于使用旧版 JSP 作为视图技术?另见When to use <ui:include>, tag files, composite components and/or custom components?
【讨论】: