簡體   English   中英

在支持組件中使用@ManagedProperty

[英]Use of @ManagedProperty in backing component

如何在支持組件中使用@ManagedProperty

這是伙伴選擇器復合組件。 該組件檢查數據庫中鍵入的伙伴代碼,如果代碼有效,則填寫伙伴名稱。

組件:

<cc:interface componentType="partnerSelComp">
    <cc:attribute name="value" type="java.lang.Long"/>
</cc:interface>

<cc:implementation>
    <span id="#{cc.clientId}" style="white-space:nowrap">
        <p:inputText id="id" type="hidden" binding="#{cc.partnerId}"/>                                     
        <p:inputText id="code" binding="#{cc.code}">                     
            <p:ajax event="blur" update="id code name" listener="#{cc.validate}" />
        </p:inputText>            
        <p:inputText id ="name" disabled="true" binding="#{cc.name}" />                   
        <p:message for="code"/>
    </span>
</cc:implementation>

encodeBegin()我得到了NPE,因為service為空:

    @FacesComponent("partnerSelComp")
    public class PartnerSelComp extends UIInput implements NamingContainer {

        private InputText partnerId;
        private InputText code;    
        private InputText name; 

        @ManagedProperty("#{partnerService}")
        private PartnerService service;

        @Override
        public void encodeBegin(FacesContext context) throws IOException {
            Partner p=null;
            Long i = (Long) getValue();        

            if (i != null) {            
               p = findPartnerById(service.getList(), i); 
           }
           fill( (i==null) , p); // fills the code and name fields
        }

   ... 


    }

這是我要訪問的bean。 (稍后它將替換為JPA查詢。)

@ManagedBean(name = "partnerService")
@ApplicationScoped
public class PartnerService {

    private List<Partner> list;

    public PartnerService() {
        list = new ArrayList<>();
        list.add( new Partner(1, "A", "Partner A"));
        list.add( new Partner(2, "B", "Partner B"));
        list.add( new Partner(3, "C", "Partner C"));
        list.add( new Partner(4, "D", "Partner D"));
        list.add( new Partner(5, "E", "Partner E"));
        list.add( new Partner(6, "E", "Partner F"));        
    }

    public List<Partner> getList() {
        return list;
    }

    public void setList(List<Partner> list) {
        this.list = list;
    }

}

解決方案:

組件的使用:

<my:PartnerSelComp value="#{myBean.partnerId}" service="#{partnerService}"/>

組件xhtml:

    <cc:interface componentType="partnerSelComp">
        <cc:attribute name="value" type="java.lang.Long"/>
        <cc:attribute name="service"/>
    </cc:interface>

    <cc:implementation>
        <span id="#{cc.clientId}" style="white-space:nowrap">
            <p:inputText id="id" type="hidden" binding="#{cc.partnerId}"/>                                     
            <p:inputText id="code" binding="#{cc.code}">                     
                <p:ajax event="blur" update="id code name" listener="#{cc.validate}" />
            </p:inputText>            
            <p:inputText id ="name" disabled="true" binding="#{cc.name}" />                   
            <p:message for="code"/>
        </span>
    </cc:implementation>

我注意到,我嘗試過將引用作為屬性默認值傳遞: <cc:attribute name="service" default="#{partnerService}"/><my:PartnerSelComp value="#{myBean.partnerId}"/>我不知道為什么,但是它沒有用,我不得不在my:PartnerSelComp設置service屬性,如上所示。

和支持組件:

    @FacesComponent("partnerSelComp")
    public class PartnerSelComp extends UIInput implements NamingContainer {

        private InputText partnerId;
        private InputText code;    
        private InputText name; 

        @ManagedProperty("#{partnerService}")
        private PartnerService service;

        @Override
        public void encodeBegin(FacesContext context) throws IOException {
            Partner p=null;
            Long i = (Long) getValue();        

            PartnerService service = getAttributeValue("service", null );         

            if (i != null) {            
               p = findPartnerById(service.getList(), i); 
           }
           fill( (i==null) , p); // fills the code and name fields
        }

        @SuppressWarnings("unchecked")
        private <T> T getAttributeValue(String key, T defaultValue) {
            T value = (T) getAttributes().get(key);
            return (value != null) ? value : defaultValue;
        }

   ... 

    }

我必須使用getAttributes().get(key)來獲取引用並將其轉換為PartnerService

感謝您的回答。

嘗試使用html配置界面加載它:

<cc:interface componentType="partnerSelComp">
    <cc:attribute name="value" type="java.lang.Long"/>
    <cc:attribute name="service" default="#{partnerService}"/>
</cc:interface>

這主要是為了在html實現內部使用,就像在bean類內部一樣,您還是必須手動獲取它:

FacesContext.getCurrentInstance().getAttributes().get("service");

關於直接注入@FacesComponent,直到下一個JSF(2.3)版本才有可能。

可能的解決方法是使用"@Named代替@FacesComponent或者如果您不能這樣做,則嘗試使用http://omnifaces.org/庫的某些功能。它可以注入@FacesConverter,因此您可以也將其應用於此注釋。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM