jsf - मैं डेटा के अंदर कमांड लिंक में चयनित पंक्ति कैसे पास कर सकता हूंटेबल या ui: दोहराना?




jsf-2 datatable (3)

कारण के रूप में, <f:attribute> घटक के लिए विशिष्ट है (दृश्य निर्माण समय के दौरान आबादी), पुनरावृत्त पंक्ति (दृश्य प्रस्तुत समय के दौरान पॉप्युलेट) के लिए नहीं।

आवश्यकता को प्राप्त करने के कई तरीके हैं।

  1. इसके बजाए <f:param> प्रयोग करें। यह एक अनुरोध पैरामीटर जोड़ता है।

    <h:commandLink action="#{bean.insert}" value="insert">
        <f:param name="id" value="#{item.id}" />
    </h:commandLink>
    

    यदि आपका बीन अनुरोधित है, तो JSF को इसे @ManagedProperty द्वारा सेट करें

    @ManagedProperty(value="#{param.id}")
    private Long id; // +setter
    

    या यदि आपके बीन का व्यापक दायरा है या यदि आप अधिक बढ़िया अनाज सत्यापन / रूपांतरण चाहते हैं, तो लक्ष्य दृश्य पर <f:viewParam> उपयोग करें, यह भी देखें f: viewParam vs @ManagedProperty :

    <f:viewParam name="id" value="#{bean.id}" required="true" />
    

    किसी भी तरह से, इसका लाभ यह है कि डेटामोडेल को फॉर्म जमा करने के लिए जरूरी नहीं है (यदि आपके बीन का अनुरोध किया गया है)।

  2. इसके बजाय <f:setPropertyActionListener> उपयोग करें। लाभ यह है कि जब अनुरोध दायरे से बीन का व्यापक दायरा होता है तो यह अनुरोध पैरामीटर मानचित्र तक पहुंचने की आवश्यकता को हटा देता है।

    <h:commandLink action="#{bean.insert}" value="insert">
        <f:setPropertyActionListener target="#{bean.id}" value="#{item.id}" />
    </h:commandLink>
    

    के साथ सम्मिलन में

    private Long id; // +setter
    

    यह केवल एडी विधि में संपत्ति id द्वारा उपलब्ध होगा। यह केवल इतना है कि डेटामैडल फॉर्म सबमिट अनुरोध के लिए संरक्षित है। सबसे अच्छा है कि बीन को व्यू स्कोप में @ViewScoped द्वारा @ViewScoped

  3. यदि आपका सर्वलेट कंटेनर सर्वलेट 3.0 / ईएल 2.2 का समर्थन करता है, तो बस इसे विधि तर्क के रूप में पास करें। यह भी आवश्यक है कि फॉर्म सबमिट करने के लिए डेटामैडल संरक्षित है। सबसे अच्छा है कि बीन को व्यू स्कोप में @ViewScoped द्वारा @ViewScoped

    <h:commandLink action="#{bean.insert(item.id)}" value="insert" />
    

    के साथ सम्मिलन में:

    public void insert(Long id) {
        // ...
    }
    

    आप पूरे आइटम ऑब्जेक्ट को भी पास कर सकते हैं:

    <h:commandLink action="#{bean.insert(item)}" value="insert" />
    

    साथ में:

    public void insert(Item item) {
        // ...
    }
    

    सर्वलेट 2.5 कंटेनर पर, यह भी संभव है यदि आप ईएल कार्यान्वयन की आपूर्ति करते हैं जो इसका समर्थन करता है, जैसे कि जेबॉस ईएल। कॉन्फ़िगरेशन विवरण के लिए, यह उत्तर देखें।

  4. DataModel<E> लिए DataModel<E> मान को बाध्य करें जिसके बदले में आइटम लपेटें।

    <h:dataTable value="#{bean.model}" var="item">
    

    साथ में

    private transient DataModel<Item> model;
    
    public DataModel<Item> getModel() {
        if (model == null) {
            model = new ListDataModel<Item>(items);
        }
        return model;
    }
    

    (इसे transient आलसी और आलसी रूप से इसे चालू करना अनिवार्य है जब आप इसे किसी दृश्य या सत्र DataModel बीन पर उपयोग कर रहे हैं क्योंकि DataModel Serializable लागू नहीं करता है)

    फिर आप DataModel#getRowData() किसी भी चीज़ को पास किए बिना वर्तमान पंक्ति तक पहुंच पाएंगे (जेएसएफ क्लिक किए गए कमांड लिंक / बटन के अनुरोध पैरामीटर नाम के आधार पर पंक्ति निर्धारित करता है)।

    public void insert() {
        Item item = model.getRowData();
        Long id = item.getId();
        // ...
    }
    

    यह भी आवश्यक है कि फॉर्म सबमिट करने के लिए डेटामैडल संरक्षित है। सबसे अच्छा है कि बीन को व्यू स्कोप में @ViewScoped द्वारा @ViewScoped

  5. आप वर्तमान #{item} का प्रोग्रामेटिक मूल्यांकन करने के लिए Application#evaluateExpressionGet() उपयोग कर सकते हैं।

    public void insert() {
        FacesContext context = FacesContext.getCurrentInstance();
        Item item = context.getApplication().evaluateExpressionGet(context, "#{item}", Item.class);
        Long id = item.getId();
        // ...
    }
    

चुनने का कौन सा तरीका कार्यात्मक आवश्यकताओं पर निर्भर करता है और क्या एक या दूसरा अन्य प्रयोजनों के लिए अधिक फायदे प्रदान करता है। मैं व्यक्तिगत रूप से # 3 के साथ आगे बढ़ता हूं, या जब आप सर्वलेट 2.5 कंटेनरों का समर्थन करना चाहते हैं, साथ ही # 2 के साथ।

मैं जेएसएफ 2 एप्लिकेशन में प्राइमफेसेस का उपयोग कर रहा हूं। मेरे पास <p:dataTable> , और पंक्तियों को चुनने के बजाय, मैं चाहता हूं कि उपयोगकर्ता व्यक्तिगत पंक्तियों पर विभिन्न कार्रवाइयों को सीधे निष्पादित करने में सक्षम हो। इसके लिए, मेरे पास पिछले कॉलम में कई <p:commandLink> s हैं।

मेरी समस्या: मैं कमांड लिंक द्वारा शुरू की गई कार्रवाई के लिए एक पंक्ति आईडी कैसे पास कर सकता हूं ताकि मुझे पता चले कि कौन सी पंक्ति पर कार्य करना है? मैंने <f:attribute> का उपयोग करने का प्रयास किया:

<p:dataTable value="#{bean.items}" var="item">
    ...
    <p:column>
        <p:commandLink actionListener="#{bean.insert}" value="insert">
            <f:attribute name="id" value="#{item.id}" />
        </p:commandLink>
    </p:column>
</p:dataTable>

लेकिन यह हमेशा 0 उत्पन्न करता है - स्पष्ट रूप से पंक्ति परिवर्तनीय f उपलब्ध नहीं है जब विशेषता प्रदान की जाती है (जब मैं एक निश्चित मान का उपयोग करता हूं तो यह काम करता है)।

किसी के पास वैकल्पिक समाधान है?


जेएसएफ 1.2 में यह <f:setPropertyActionListener> (कमांड घटक के भीतर) द्वारा किया गया था। जेएसएफ 2.0 में (ईएल 2.2 सटीक होना, बलससी के लिए धन्यवाद) ऐसा करना संभव है: action="${filterList.insert(f.id)}


मैकॉन्ग द्वारा इस साइट के लिए धन्यवाद, एकमात्र समाधान जो वास्तव में पैरामीटर पास करने के लिए हमारे लिए काम करता था, यह था

<h:commandLink action="#{user.editAction}">
    <f:param name="myId" value="#{param.id}" />
</h:commandLink>

साथ में

public String editAction() {

  Map<String,String> params = 
            FacesContext.getExternalContext().getRequestParameterMap();
  String idString = params.get("myId");
  long id = Long.parseLong(idString);
  ...
}

तकनीकी रूप से, कि आप सीधे विधि को पास नहीं कर सकते हैं, लेकिन JSF request parameter map





commandlink