আমি কীভাবে নির্বাচিত সারিতে ডেটা টেবিলের মধ্যে কমান্ডলিংক বা ইউআই: পুনরাবৃত্তি করতে পারি?


100

আমি জেএসএফ 2 অ্যাপ্লিকেশনটিতে প্রাইমফেস ব্যবহার করছি। আমার একটি রয়েছে <p:dataTable>এবং সারিগুলি নির্বাচন করার পরিবর্তে আমি চাই যে ব্যবহারকারী স্বতন্ত্র সারিগুলিতে সরাসরি বিভিন্ন ক্রিয়া সম্পাদন করতে সক্ষম হয়। তার জন্য, আমি <p:commandLink>শেষ কলামে বেশ কয়েকটি এস করেছি ।

আমার সমস্যা: কমান্ড লিঙ্ক দিয়ে শুরু করা ক্রিয়ায় আমি কীভাবে একটি সারি আইডি পাস করতে পারি যাতে আমি জানতে পারি যে কোন সারিতে কাজ করা উচিত? আমি এটি ব্যবহার করার চেষ্টা করেছি <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এট্রিবিউটটি যখন রেন্ডার করা হয় তখন দৃশ্যত সারি ভেরিয়েবলটি পাওয়া যায় না (যখন আমি একটি নির্দিষ্ট মান ব্যবহার করি তখন এটি কাজ করে)।

কারও বিকল্প সমাধান আছে?

উত্তর:


215

কারণ হিসাবে, এটি <f:attribute>উপাদানটি নিজেই সুনির্দিষ্ট (ভিউ তৈরির সময় জনবহুল), পুনরাবৃত্ত সারিতে নয় (ভিউ রেন্ডার সময় পপুলেটেড)।

প্রয়োজনীয়তা অর্জনের বিভিন্ন উপায় রয়েছে।

  1. যদি আপনার সার্লেটলেট কনটেনারয়ার সর্বনিম্ন servlet 3.0 / EL 2.2 সমর্থন করে, তবে কেবল এটি UICommand উপাদান বা AjaxBehaviorট্যাগের ক্রিয়া / শ্রোতার পদ্ধতির যুক্তি হিসাবে পাস করুন । যেমন

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

    আমি তাল মিলাতে চেষ্টা করছি:

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

    এটির জন্য কেবলমাত্র ফর্ম জমা দেওয়ার অনুরোধের জন্য ডেটামোডেল সংরক্ষণ করা দরকার। শিমটি দ্বারা দেখার সুযোগে রাখা ভাল @ViewScoped

    আপনি এমনকি পুরো আইটেম অবজেক্টটি পাস করতে পারেন:

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

    সঙ্গে:

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

    সার্ভলেট 2.5 পাত্রে, আপনি যদি EB বাস্তবায়ন সরবরাহ করে যা এটি JBoss EL এর মতো সরবরাহ করে তবে এটিও সম্ভব। কনফিগারেশন বিশদ জন্য, এই উত্তর দেখুন


  2. ব্যবহারের <f:param>মধ্যে UICommandঅংশ। এটি একটি অনুরোধের প্যারামিটার যুক্ত করে।

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

    যদি আপনার শিমটি অনুরোধ করা হয় তবে জেএসএফ এটি সেট করুন @ManagedProperty

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

    অথবা যদি আপনার শিমের বিস্তৃত সুযোগ থাকে বা আপনি আরও সূক্ষ্ম দানযুক্ত বৈধতা / রূপান্তর চান <f:viewParam>তবে লক্ষ্য দৃশ্যে ব্যবহার করুন, এফ দেখুন: ভিউপ্যারাম বনাম @ ম্যানেজডপ্রপার্টি :

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

    যে কোনও উপায়ে, এর সুবিধা রয়েছে যে ডেটামোডেলটি ফর্ম জমা দেওয়ার জন্য অগত্যা সংরক্ষণ করার প্রয়োজন নেই (যে ক্ষেত্রে আপনার শিমটি অনুরোধের অনুরোধ রইল)।


  3. ব্যবহারের <f:setPropertyActionListener>মধ্যে UICommandঅংশ। সুবিধাটি হ'ল বিলের অনুরোধের সুযোগের চেয়ে বিস্তৃত সুযোগ থাকলে এটি অনুরোধের প্যারামিটার মানচিত্রে অ্যাক্সেসের প্রয়োজনীয়তা সরিয়ে দেয়।

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

    আমি তাল মিলাতে চেষ্টা করছি

     private Long id; // +setter
    

    এটি idক্রিয়া পদ্ধতিতে সম্পত্তি দ্বারা কেবল উপলব্ধ হবে । এটির জন্য কেবলমাত্র ফর্ম জমা দেওয়ার অনুরোধের জন্য ডেটামোডেল সংরক্ষণ করা দরকার। শিমটি দ্বারা দেখার সুযোগে রাখা ভাল @ViewScoped


  4. 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প্রয়োগ করেন না তখন এটি তৈরি করা এবং অলসভাবে এটিকে গিটারে ইনস্ট্যান্ট করা বাধ্যতামূলক Serializable)

    তারপরে আপনি DataModel#getRowData()কিছু না কাটিয়ে বর্তমান সারিটি অ্যাক্সেস করতে সক্ষম হবেন (জেএসএফ ক্লিক করা কমান্ডের লিঙ্ক / বোতামের অনুরোধ প্যারামিটার নামের উপর ভিত্তি করে সারিটি নির্ধারণ করে)।

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

    এটিরও প্রয়োজন যে ফর্ম জমা দেওয়ার অনুরোধের জন্য ডেটামোডেল সংরক্ষণ করা উচিত। শিমটি দ্বারা দেখার সুযোগে রাখা ভাল @ViewScoped


  5. Application#evaluateExpressionGet()প্রোগ্রামটিমেটিকভাবে বর্তমানটির মূল্যায়ন করতে ব্যবহার করুন #{item}

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

কোনটি বেছে নেবেন তা কার্যকরী প্রয়োজনীয়তার উপর নির্ভর করে এবং এক বা অন্যটি অন্যান্য উদ্দেশ্যে আরও সুবিধা দেয় কিনা। আমি ব্যক্তিগতভাবে # 1 বা যখন আপনি # 2 দিয়ে সারোলেট 2.5 কন্টেইনার সমর্থন করতে চান তখন এগিয়ে যাব #


4
+1, যদিও আমার অগ্রাধিকারটি # 2 এ যায় (যদি 2.5 টি সমর্থন করে তবে)।
বোঝো

সম্পূর্ণ উত্তরের জন্য ধন্যবাদ। দুর্ভাগ্যক্রমে, আমাকে জানাতে হবে যে # 1 কেবলমাত্র একটি ফিল্টার প্রাইমফেসগুলি ডেটাটেবলের মধ্যে কাজ করেছিল (যা ঠিক আমার জন্য এটির প্রয়োজন পরিস্থিতি)। বাকি সমস্তগুলি কেবল একটি ছাপানো টেবিলে কাজ করেছিল। যদিও আমি আপনার উত্তরের চেয়ে প্রাইমফেসে একটি বাগ হিসাবে এটি দেখতে পাচ্ছি।
মাইকেল বর্গওয়ার্ট

শিমের অনুরোধ বা দৃশ্যটি বাদ দেওয়া আছে?
বালুসসি

4
"ফিল্টার্ড" দিয়ে আপনি এই শোকেস উদাহরণ হিসাবে বোঝাতে চান ? লক্ষণগুলি ইঙ্গিত দেয় যে ফিল্টার ক্রিয়াটি কেবল ক্লায়েন্টের পক্ষেই হয় এবং এটি সার্ভারের সাইডে থাকা মডেলটি বজায় থাকে না। এটি উদ্দেশ্যমূলক কিনা তা নিশ্চিত নয় Not আপনি সর্বদা একটি সমস্যা প্রতিবেদন ছেড়ে দিতে পারেন।
বালুসসি

আপনার পোস্টটি আমি পড়েছি সবচেয়ে দরকারী পোস্টের মধ্যে। আমি পদ্ধতি 5 ব্যবহার করেছি কারণ আমাকে সার্লেটটি 2.5 ব্যবহার করতে বাধ্য করা হয়েছে। এখন আমার প্রশ্নটি হ'ল কমান্ডলিংকের সাথে পরামিতি পাঠানো সম্ভব (যেমন আপনার উদাহরণের মতো) তবে এজাক্স ব্যবহার করছেন?
অ্যাডিজু

11

জেএসএফ ১.২ এ এটি করা হয়েছিল <f:setPropertyActionListener>(কমান্ড উপাদানটির মধ্যে)। জেএসএফ ২.০-তে (EL 2.2 সুনির্দিষ্টভাবে বলার জন্য, বালাসসিকে ধন্যবাদ) এটি এর মতো করে করা সম্ভব:action="${filterList.insert(f.id)}


6
এই বৈশিষ্ট্যটি জেএসএফ ২.০ (যা নিজে সার্ভলেট ২.৫ ধারকগুলিতে চালাতে পারে) এর সাথে সুনির্দিষ্ট নয়, তবে ইএল ২.২ (যা সার্লেট ৩.০ এর অংশ)।
BalusC

11

আমার দর্শন পৃষ্ঠায়:

<p:dataTable  ...>
<p:column>
<p:commandLink actionListener="#{inquirySOController.viewDetail}" 
               process="@this" update=":mainform:dialog_content"
           oncomplete="dlg2.show()">
    <h:graphicImage library="images" name="view.png"/>
    <f:param name="trxNo" value="#{item.map['trxNo']}"/>
</p:commandLink>
</p:column>
</p:dataTable>

ব্যাকিং শিম

 public void viewDetail(ActionEvent e) {

    String trxNo = getFacesContext().getRequestParameterMap().get("trxNo");

    for (DTO item : list) {
        if (item.get("trxNo").toString().equals(trxNo)) {
            System.out.println(trxNo);
            setSelectedItem(item);
            break;
        }
    }
}

-1

মাইকংয়ের এই সাইটের জন্য ধন্যবাদ , বাস্তবে আমাদের পরামিতিটি পাস করার একমাত্র সমাধানটি হ'ল এটি

<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


4
আপনি এখানে জিজ্ঞাসা চেয়ে ভিন্ন সমস্যা আছে। আপনি #{param}পরবর্তী অনুরোধগুলির জন্য মানচিত্র থেকে অনুরোধের পরামিতিগুলি ধরে রাখতে চান , স্বেচ্ছাচারিত প্যারামিটারটি পাস না করে। তোমার Q & A- আওতায় পড়ে stackoverflow.com/questions/17734230
BalusC
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.