كيف يمكنك تمرير المعلمات عرض عند التنقل من إجراء في JSF2؟
سؤال
من إجراء في الفاصولي ، أحاول إعادة التوجيه إلى صفحة أخرى أتوقع معلمة عرض. ما هي الطريقة الموصى بها للقيام بذلك في JSF2؟
على سبيل المثال ، قل صفحة المصدر الخاصة بي هي:http: //localhost/page1.xhtml
إنه يحتوي على قيادة يدعو الإجراء:
<h:commandButton value="submit" action="#{myBean.submit}" />
حيث تبدو الفاصولي:
@ManagedBean
@RequestScoped
public class MyBean {
private int id;
public String submit() {
//Does stuff
id = setID();
return "success";
}
والآن ، أريد عودة "إرسال" إلى التنقل إلىhttp: //localhost/page2.xhtml؟ id = 2
لقد حاولت القيام بذلك مع عرض عرضي في حالة التنقل الخاصة بي ، ولكن بنتائج غريبة. يشبه مقتطف الوجوه-Config ما يلي:
<navigation-rule>
<from-view-id>/page1.xhtml</from-view-id>
<navigation-case>
<from-outcome>success</from-outcome>
<to-view-id>/page2.xhtml</to-view-id>
<redirect>
<view-param>
<name>id</name>
<value>#{myBean.id}</value>
</view-param>
</redirect>
</navigation-case>
</navigation-rule>
إن السلوك الغريب الذي يجري ، على الرغم من أن MyBean قد تم تعيينه على طلب Scoped ، إلا أنه يستدعي MyBean.getId () في المرة الأولى التي أقوم فيها بتحميل طلبي ، وإعادة استخدام نفس القيمة لجميع المكالمات اللاحقة ، مما ينتج عنه معلمات عرض غير صحيحة لـ Page2.
لذلك أنا أبحث إما طريقة أفضل للقيام بذلك ، أو سبب/حل لسبب عدم طلب عرض العرض من الفاصولي في كل مرة.
المحلول
إن الشيء غير البديهي حول تمرير المعلمات في JSF هو أنك لا تقرر ما الذي ترسله (في الإجراء) ، بل ما ترغب في تلقيه (في الصفحة المستهدفة).
عندما تقوم بإجراء ينتهي بإعادة توجيه ، يتم تحميل بيانات تعريف الصفحة المستهدفة ويتم قراءة جميع المعلمات المطلوبة وإلحاقها بعنوان URL كمعلمات.
لاحظ أن هذه هي نفس الآلية تمامًا كما هو الحال مع أي ملزمة JSF أخرى: لا يمكنك قراءة قيمة InputText من مكان واحد وجعلها تكتب في مكان آخر. يتم استخدام تعبير القيمة المحدد في ViewParam للقراءة (قبل إعادة التوجيه) والكتابة (بعد إعادة التوجيه).
مع الفول الخاص بك فقط تفعل:
@ManagedBean
@RequestScoped
public class MyBean {
private int id;
public String submit() {
//Does stuff
id = setID();
return "success?faces-redirect=true&includeViewParams=true";
}
// setter and getter for id
إذا كان الجانب المتلقي يحتوي على:
<f:metadata>
<f:viewParam name="id" value="#{myBean.id}" />
</f:metadata>
سوف تفعل بالضبط ما تريد.
نصائح أخرى
بدون حل أجمل ، ما وجدته في العمل هو ببساطة بناء سلسلة الاستعلام الخاصة بي في عودة الفاصوليا:
public String submit() {
// Do something
return "/page2.xhtml?faces-redirect=true&id=" + id;
}
ليس أكثر الحلول مرونة ، ولكن يبدو أنه يعمل كيف أريد ذلك.
باستخدام هذا النهج أيضًا لتنظيف عملية بناء سلسلة الاستعلام:http://www.warski.org/blog/؟p=185
تحقق من هذه:
- http://andyschwartz.wordpress.com/2009/07/31/whats-new-in-jsf-2/#get
- http://mkblog.exadel.com/2010/07/learning-jsf2-page-params-and-page-actions/
ستحتاج إلى شيء مثل:
<h:link outcome="success">
<f:param name="foo" value="bar"/>
</h:link>
...و...
<f:metadata>
<f:viewParam name="foo" value="#{bean.foo}"/>
</f:metadata>
انطلاقا من هذه الصفحة, ، قد يكون شيء من هذا القبيل أسهل:
<managed-bean>
<managed-bean-name>blog</managed-bean-name>
<managed-bean-class>com.acme.Blog</managed-bean-class>
<managed-property>
<property-name>entryId</property-name>
<value>#{param['id']}</value>
</managed-property>
</managed-bean>
يمكنك القيام بذلك باستخدام Primefaces مثل هذا:
<p:button
outcome="/page2.xhtml?faces-redirect=true&id=#{myBean.id}">
</p:button>
فقط أضف السمة المنشورة لإعادة توجيه العلامة على النحو التالي:
<redirect include-view-params="true">
<view-param>
<name>id</name>
<value>#{myBean.id}</value>
</view-param>
</redirect>
هنا هي بعض أمثلة الملاحة.
حل دون الرجوع إلى الفول:
<h:button value="login"
outcome="content/configuration.xhtml?i=1" />
في مشروعي كنت بحاجة إلى هذا النهج:
<h:commandButton value="login"
action="content/configuration.xhtml?faces-redirect=true&i=1" />