JSF 2.0: عرض حقول النماذج مع البيانات الأولية باستخدام حبوب سكان الطلب (لتحديث بيانات الخادم الخاصة بالمكون الحالي)

StackOverflow https://stackoverflow.com/questions/3812685

سؤال

حالة طبيعية جدا:

لدينا مكون مركب "مدخل" له ولايتان: موسع وينهار. تبدأ المدبرات كما تم توسيعها ، ولكن يمكن للمستخدم انهيارها عن طريق النقر عليها. يجب حفظ هذه الحالة في الجلسة ، بحيث تنحرف على الصفحة أو الانتقال إلى جديد ، تتذكر المدبرات ما إذا كانت تم توسيعها/انهيارها.

هذا هو جوهر المشكلة: كيف يمكنك بالفعل تنفيذ هذا توفير الحالة في مكون ، يمكن إدراجه على الصفحة عدة مرات؟

بعض الخلفية / الأفكار:

يمكن تحقيق تنفيذ توفير الدولة لمدخل واحد بسهولة باستخدام حبة سكنية. يمكن أيضًا دعم عدد ثابت من المدخلات من خلال إنشاء عدد ثابت من الفاصوليا المغطاة بالجلسة أو إعلان خصائص مختلفة في فول واحد. ومع ذلك ، لا أريد حتى أن أذكر لماذا هذه الأساليب سيئة.

كانت فكرتي الأولية لهذا هو إنشاء خريطة (أو بنية كائنات) ضمن حبة جلسة واحدة لعقد الحالات لجميع المدخلات. ومع ذلك ، لا يمكنني الرجوع مباشرة إلى هذه البيانات من JSF (بحيث يقوم JSF أيضًا بتحديثها). لقد فكرت في كتابة getter/setter محددة لجلب/تحديث القيمة الصحيحة في الخريطة ، ولكن هذا غير ممكن لأنه لا يوجد بيانات تحديد أثناء تنفيذ getters والمستقبين.

ومع ذلك ، من الواضح أنني بحاجة إلى إنقاذ الولايات في حبة جلسة. يمكنني القيام بتوفير الدولة بسهولة عن طريق نشر نموذج مع f:ajax وتنفيذ طريقة خاصة باستخدام listener والبيانات المقدمة. من أجل دعم مثيلات متعددة للمكون ، يمكنني استخدام (مثيلات متعددة) بين الفول المغطى بالطلب للتعامل مع كل توسيع/انهيار. ومع ذلك ، من أجل نشر البيانات التي تحدد المدخل وحالتها فعليًا ، أحتاج أولاً إلى إدراجها في حقول النموذج في وقت العرض.

لذا ، كيف تزود كل مدخل فعليًا بالبيانات الصحيحة في وقت العرض (في الواقع مجرد حالة منطقية/تعداد في هذه الحالة ، ولكن النظر في حالة يجب معالجة المزيد من البيانات)؟

يبدو أن:

  • h:inputHidden و h:inputText لا تدعم تعيين القيمة الأولية بخلاف القيمة (التي قد تشير إلى #{portletBean.portletState}).
  • لا يمكنني تحميل حبوب الطلب تلقائيًا مع القيم الأولية المناسبة في وقت إنشاءها ، حيث لا توجد معلومات تعريف متاحة.

مرة أخرى ، يبدو الأمر وكأنني أفتقد شيئًا ... مؤشرات؟

أفترض أن واحدة على الأقل من الإجابات ستكون للاستخدام UIComponent بدلاً من المكونات المركبة ، لكني أرغب في الحفاظ على هذا المكون المركب لأنه يحتوي على الكثير من عناصر HTML الخام.

تحديث:

  • هناك سؤال مماثل, ، مع اقتراح لاستخدام الفاصوليا المنقوقة. لا أعتقد أن هذا قابل للحياة هنا.
هل كانت مفيدة؟

المحلول 3

لقد استخدمت أ تم حلها مسبقًا لاستدعاء طريقة الفول من JS:

أنشأ شكل فارغ غير مرئي ، مع h:commandButton و f:ajax داخلها الاتصال listener.

إنشاء زر منفصل لإطلاق حدث توسيع/انهيار. من هذا الزر ، يبدأ طريقة JavaScript ، حيث ينشط التوسع/الانهيار وفي الوقت نفسه ينقر على الزر المخفي داخل النموذج. يتم إرسال جميع البيانات المطلوبة باستخدام listener ينسب. يستهدف المستمع حبة جلسة ، تقوم بفحص/تحديث خريطة للحالات ، والتي تم تحديدها بواسطة معرفات عميل المكون.

هذا بسيط جدًا ، أتساءل لماذا لم أدرك أنه eariler ...

ومع ذلك ، فإنه لا يزال بعيدًا عن الكمال ولا يجيب على كيفية بدء الفاصوليا المغطاة بالطلب بقيم افتراضية لاستخدامها كنموذج للتخزين/النقل.

نصائح أخرى

حصلت على عدد قليل من الاختراقات الممكنة لهذا الغرض. سأقوم بنشرهم هنا ولكني لا أعتقد أن هذه هي الطريق للذهاب:

استخدم JavaScript لتعيين حقول النماذج مع البيانات الصحيحة مباشرة بعد تقديم:

window.addEvent('domready', function() {
    var portletState = '#{portletBean.getPortletState(cc.attrs.clientId)}';
    // find the field and set the data...
});

يشعر بالاختراق. لا أريد أن آخذ هذا الطريق.

استخدم خريطة سمة المكون للاحتفاظ بالبيانات:

<cc:interface>
    <cc:attribute name="portletState" default="#{portletBean.getPortletState(cc.attrs.clientId)}" />
</cc:interface>

الوصول إلى ذلك من الكود:

public void stateChangedCallback(String clientId) {
    UIComponent component = FacesContext.getCurrentInstance().getViewRoot().findComponent(clientId);
    String state = (String) component.getAttributes().get("portletState");
}

أيضا لا يشعر على صواب. كما أنني لست متأكدًا مما إذا كان يعمل (هل يمكنك بالفعل استخدام EL في الجدير الافتراضي).

استخدم خريطة سمة المكون لعقد البيانات من خلال توفيرها عند الاتصال بالمكون:

<portlet:portlet id="specificPortlet">
    <f:attribute name="portletState" value="#{portletBean.getPortletState(component.clientId)}" />
</portlet:portlet>

مرة أخرى ، خرقاء للغاية وتكرر الكود الخاص بك.

يمكنك القيام بذلك باستخدام taglibs ، يمكنك نقل المعلمات إلى علامات:

أضف ما يلي إلى taglib الخاص بك:

<tag>
    <tag-name>date</tag-name>
    <source>components/date.xhtml</source>
</tag>

ثم هنا محتويات المكونات/date.xhtml

<ui:composition name="date_template">
    <h:panelGrid id="#{id}Panel" columns="1" border="0" cellpadding="0" cellspacing="0">
        <rich:calendar immediate="true" id="#{id}" popup="true" datePattern="dd.MM.yyyy"
                        enableManualInput="true" showApplyButton="true" cellWidth="12px" cellHeight="11px" style="width:100px"
                        value="#{dateForm.date}" required="#{required}" readonly="#{readonly}" validator="#{dateForm.validateDate}">
            <a4j:support event="onchanged" reRender="#{id}Panel,#{reRenderDate}"/>
            <ui:insert />
        </rich:calendar>

        <rich:message for="#{id}" errorClass="error" />
    </h:panelGrid>
</ui:composition>

ثم تستخدم هذا مثل:

<adse:date id="dateTransfert" required="true"
           dateForm="#{dossierBean.dateTransfert}"
           readonly="false" reRenderDate="montantAncien,montantNouveau,montantEmolument">
     <a4j:support event="oninputblur" reRender="dateTransfertPanel,montantAncien,montantNouveau,montantEmolument"/>
</adse:date>

في هذه الحالة ، يتم تمرير DateForm ، وهذا كائن ، وفي taglib نستخدم خصائص هذا الكائن (DateForm.date). لاحظ أيضاu003Cui:insert /> والتي يمكن استخدامها لتضمين عناصر أخرى في XHTML.

لذلك ، يمكنك أن تمر في سياق كل مدخل. يمكنك حتى جعل هذا المعيار من خلال وجود Portletbean كطابق فائق تحدد طريقة getPortletState ().

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top