سؤال

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

هنا هو XHTML.

<xhtml:head>
    <xforms:model id="main" 
                  xxforms:session-heartbeat="true"
                  xxforms:show-error-dialog="false" 
                  xxforms:external-events="submit-save submit-preview submit-cancel">

        <xforms:instance id="instance">
            <root>
                <repeat>
                    <item>
                        <title/>
                    </item>
                </repeat>           
            </root>
        </xforms:instance>

        <xforms:instance id="proto-property">
            <item>
                <title/>
            </item>
        </xforms:instance>

        <xforms:bind nodeset="instance('instance')">
            <xforms:bind
                nodeset="repeat/item/title"
                required="true()" />
        </xforms:bind>

    </xforms:model>
    <xbl:xbl xmlns:xhtml="http://www.w3.org/1999/xhtml"
     xmlns:xforms="http://www.w3.org/2002/xforms"
     xmlns:xs="http://www.w3.org/2001/XMLSchema"
     xmlns:ev="http://www.w3.org/2001/xml-events"
     xmlns:xi="http://www.w3.org/2001/XInclude"
     xmlns:xxi="http://orbeon.org/oxf/xml/xinclude"
     xmlns:xxforms="http://orbeon.org/oxf/xml/xforms"
     xmlns:fr="http://orbeon.org/oxf/xml/form-runner"
     xmlns:saxon="http://saxon.sf.net/"
     xmlns:oxf="http://www.orbeon.com/oxf/processors"
     xmlns:xbl="http://www.w3.org/ns/xbl"
     xmlns:xxbl="http://orbeon.org/oxf/xml/xbl"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xbl:script src="/apps/xforms-sandbox/samples/input-counted.js" />

    <xbl:binding id="fr-input-counted" element="fr|input-counted">
        <xbl:template xxbl:transform="oxf:unsafe-xslt">
            <xsl:transform version="2.0">
                <xsl:import href="oxf:/oxf/xslt/utils/xbl.xsl" />
                <xsl:template match="/*">
                    <xforms:group xbl:attr="model context ref bind" xxbl:scope="outer">

                        <xbl:content includes="xforms|label" />                             

                        <xsl:copy-of select="xxbl:parameter(., 'max')" />

                        <xxforms:script ev:event="xforms-enabled" ev:target="#observer">
                            YAHOO.xbl.fr.InputCounted.instance(this).initialize();
                        </xxforms:script>

                        <xforms:group xxbl:scope="inner">
                            <xxforms:variable name="binding" as="node()?">
                                <xxforms:sequence select="." xxbl:scope="outer"/>
                            </xxforms:variable>
                            <xforms:input id="input-counted" class="fr-input-counted" ref="$binding" incremental="true" />
                            <label class="counter-label"></label>
                        </xforms:group>
                    </xforms:group>
                </xsl:template>
            </xsl:transform>
        </xbl:template>
    </xbl:binding>

</xbl:xbl>

</xhtml:head>

<xhtml:body class="body">

    <div>
        <xforms:trigger appearance="full">
            <xforms:label>
              Add Another  
            </xforms:label>
            <xforms:insert ev:event="DOMActivate" at="1"
            nodeset="repeat/item"/>
        </xforms:trigger>
    </div>

    <xforms:repeat nodeset="repeat/item">
        <div>
            <fr:input-counted ref="title" max="10">
                <xforms:label>Node Selector </xforms:label>
            </fr:input-counted>
        </div>
    </xforms:repeat>
</xhtml:body>

حاول النقر فوق إضافة آخر عدة مرات وسترى أنه لا يملأ الحجم بجوار مربع الإدخال.

يمكنك تنزيل ملف JS المطلوب من عنوان URL التالي. (http://orbeon-forms-ops-users.24843.n4.nabble.com/error-in-repeat-for-controls-having-reelevant-td2331649.html#a2533819). إنه نفس الخطأ ولكنه جعل الأمر بسيطًا عن طريق إزالة الصلة.

أنا أستخدم Orbeon 3.8 و Xforms.js Line 3798 لديه الرمز التالي. إذا كان لدي "AT" السمة في إدراجها لا تذهب إلى الداخل. هذا لأنني أحاول إدخال صف حيث تم تهيئة صف سابقًا.

                    if (! this.initialized) {
                        originalInit.call(this);
                        this.initialized = true;
                    }

هل هذا خطأ؟

شكرا لك بينش جومادي

هل كانت مفيدة؟

المحلول

شيئان:

أولاً ، تأكد من استدعاء الطريقة المستخدمة لتهيئة كائنك init() (ليس initialize()). هذا لأن السباكة التي يتم حقنها عند الاتصال ORBEON.xforms.XBL.declareClass() تأكد من أنه في كل مرة تتصل فيها instance(), ، إذا تعذر العثور على مثيل للمكون الحالي ، يتم إنشاء أحدهما ، و init() يتم استدعاؤه على هذا الكائن. كما يضمن ذلك init() يسمى مرة واحدة فقط.

ثانياً ، إضافة xxforms-iteration-moved بالإضافة إلى xforms-enabled إلى الأحداث التي تسبب تهيئة كائن XBL:

<xxforms:script ev:event="xforms-enabled xxforms-iteration-moved" ev:target="#observer">
    YAHOO.xbl.fr.InputCounted.instance(this).init();
</xxforms:script>

مع هذين التغييرين ، مما يمكنني رؤيته ، يبدو أن المكون يتم تهيئته بشكل صحيح (أحصل على 0/10 في كل سطر بعد حقل النص).

نصائح أخرى

https://gist.github.com/768034

هنا هو النسخة المبسطة من نفس الخطأ. عندما يصبح التحكم ذا صلة بعد جعل طريقة init غير ذات صلة لا تسمى والتي تعود إلى ملاحظتي السابقة (XForms.JS Line 3798).

خطوات للتكاثر

  1. راقب تنبيهين عند تحميل الصفحة
  2. قم بإلغاء تحديد خانة الاختيار
  3. حدد خانة الاختيار (راقب تنبيه واحد فقط. لا يتم عرض التنبيه "المهيئ")

هل هذا هو السلوك الصحيح؟

(هذه إجابة للمتابعة سؤال تم نشره كإجابة في هذه الصفحة. هدب.)

نعم ، هذا هو السلوك المقصود ، وأنا أفهم كيف يمكن أن يكون هذا الارتباك. فكرة init() الطريقة هي تهيئة كائن JavaScript الخاص بك والقيام ببعض التهيئة إلى DOM. إذا حصلت على مثيل لكائنك instance(), ، سيتم استدعاء هذه الطريقة تلقائيًا لك قبل استدعاء أي طريقة أخرى على كائنك.

هذا ما يفسر لماذا لا ترى init() يسمى عندما يتم تمكين المكون الخاص بك مرة أخرى. ما تريد القيام به هنا هو تقسيم الكود الخاص بك في init() داخل:

  • الجزء الذي يهيئة المكون حقًا - الذي تحتفظ به init().
  • الجزء الذي يغير ظهور المكون الخاص بك بحيث يظهر على أنه ممكّن - وهو ما تضعه بطريقة جديدة enabled().

ثم تكتب:

<xxforms:script ev:event="xforms-enabled">
    YAHOO.xbl.fr.InputCounted.instance(this).enabled();
</xxforms:script>

لاحظ أنك لست بحاجة إلى الاتصال init() صراحة سيتم ذلك من أجلك قبل أن تسمى أي طريقة أخرى. يتم القيام بشيء مماثل في الكود ل FR: زر.

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