Primefaces号码:就地:如何更优雅传播EL表达式实体合并(Primefaces p:inpl

2019-06-26 03:58发布

我想和大家分享以下强大的“黑客”在其值如采用对已编辑的实体越来越:就地。

我的问题是关于如何这个更优雅实现利用对现有的其他属性:就地或以其他方式。

诀窍是改编自#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新属性:就地专门用于此目的。

文章来源: Primefaces p:inplace: How to more elegantly propagate the EL expression for entity to merge