我想和大家分享以下强大的“黑客”在其值如采用对已编辑的实体越来越:就地。
我的问题是关于如何这个更优雅实现利用对现有的其他属性:就地或以其他方式。
诀窍是改编自#2的建议通过BalusC:
JSF(和PrimeFaces)如何参数传递到在ManagedBean的方法
现在的问题有涉及获得在具有AP Employee对象:就地编辑#{} emp.firstName:
<h:outputText value="First name:"/>
<p:inplace id="firstname" editor="true">
<p:ajax event="save" onsuccess="#{employeeController.saveName()}"/>
<p:inputText id="firstName" value="#{emp.firstName}"
required="true" label="text"
valueChangeListener="#{employeeController.firstNameChanged}">
<p:ajax event="valueChange" listener="#{employeeController.onValueChangedStart}"/>
</p:inputText>
</p:inplace>
从BalusC的建议是:
假设您要真是,其中#{} EMP是暴露其var属性重复组件里面,你可以只从值变化监听器里的EL范围抓住它,如下所示:
FacesContext context = FacesContext.getCurrentInstance();
Employee employee = context.getApplication().evaluateExpressionGet(context, "#{emp}", Employee.class);
Long id = employee.getId();
这样做的问题是,EL表达(在此情况#{EMP})是硬编码的,所以这是不能重复使用。
我现在使用p的ID:就地成功传播,可以解析为一个EL表达式的侦听器内的实体的字符串,但是因为一个不能用一个点“” 在ID字符串,我来翻译每一个“” 作为hiphen“ - ”,然后将此转换为在听者的有效EL表达式。 这样我可以传播很复杂EL表达式,然后我知道要合并到数据库中的哪些实体(或任何持续性操作是必需的)。
public static String policy_convert_id_to_el_expression(String $id) {
if ($id == null) {
throw new IllegalArgumentException("null String $id");
}
return $id.replaceAll("-", ".");
}
我有一个家庭深值的实体的是包裹特定浅值,例如BooleanValue中,FloatQuantity等,每一个具体类型的getValue()方法,和一个通用瞬变getObject()方法,以及携带其它持久性元数据有关包裹浅值(如单位,作者等等)。
我有一个ValueManager支持bean有:
public void onInplaceSaveEvent(AjaxBehaviorEvent ae) {
UIComponent component = ae.getComponent();
String id = component.getId();
String $el = policy_convert_id_to_el_expression(id);
FacesContext context = FacesContext.getCurrentInstance();
Value v = context.getApplication().evaluateExpressionGet(context, "#{" + $el + "}", Value.class);
..
// merge Value entity to database (catches change to shallow wrapped value)
// and/or perform other persistence operations such as metadata updates
..
}
现在,这是一个高度可重用的策略。
例如,我有列表的getFloors()的实体OfficeBuilding,并且每个BuildingFloor有很深FloatQuantity的getArea()实体,其中FloatQuantity延伸价值。
在一个DataTable我使用var =地板超过值迭代=#{officeBuilding.floors}和编辑从而该区域的就地浅。价值:
<p:inplace
id="floor-area"
editor="true"
emptyLabel="UNDEF"
>
<p:ajax
event="save"
update="@form"
listener="#{valueManager.onInplaceSaveEvent}"
process="@this floor-area-value"
/>
<p:inputText
id="floor-area-value"
value="#{floor.area.value}"
/>
</p:inplace>
这可以被封装为一个高度可重用和方便复合部件资源/ util的/ inplaceValue.xhtml从而:
<cc:interface>
<cc:attribute name="value" type="com.example.entity.value.Value" required="true"/>
<cc:attribute name="elid" required="true"/>
</cc:interface>
<cc:implementation>
<p:inplace
id="#{cc.attrs.elid}"
editor="true"
emptyLabel="UNDEF"
>
<p:ajax
event="save"
update="@form"
listener="#{valueManager.onInplaceSaveEvent}"
process="@this #{cc.attrs.elid}-value"
/>
<p:inputText
id="#{cc.attrs.elid}-value"
value="#{cc.attrs.value.value}"
/>
</p:inplace>
</cc:implementation>
使用以上示例被称为:
<util:inplaceValue elid="floor-area" value=#{floor.area}/>
一个只是要切记要小心在指定ELID的属性,所有的“” 在EL表达式转换为hiphen“ - ”,但它就像一个大范围的复杂情况下的魅力,而且节约了大量的编码量。 这是很优雅,但它仍然是一个黑客。
问:如何可能一个更好的传播到听者访问,其价值已被编辑实体所需的EL表达式?
我也做了一个Primefaces功能建议为P A新属性:就地专门用于此目的。