orbeon вставить в повтор

У меня возникли проблемы со вставкой строки с компонентами xbl в определенную позицию. Это работает, если я вставляю строку в конец, но если я пытаюсь вставить строку в середину, тогда метод инициализации компонентов xbl не вызывается.

Вот ххтмл.

<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-relevant-td2331649.html#a2533819). Это та же ошибка, но ее упростили, удалив соответствующий файл.

Я использую Orbeon 3.8, а строка xforms.js 3798 имеет следующий код. Если у меня есть атрибут «at» во вставке, он никогда не входит внутрь. Это потому, что я пытаюсь вставить строку там, где ранее была инициализирована строка.

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

Это ошибка?

Спасибо, Бинеш Гуммади.


person BinnyG    schedule 03.11.2010    source источник
comment
Не могли бы вы создать один файл, содержащий XHTML+XBL+JS, чтобы нам было легче его воспроизвести и обновить ваш пример? Я пытался это сделать, но дошел до того, что YAHOO.xbl.fr.InputCounted.instance(this).initialize() вызывается, а initialize() нигде в вашем коде не определено. См.: pastie.org/1272744.   -  person avernet    schedule 04.11.2010
comment
Спасибо за ответ Алекс. Виноват! Пожалуйста, посмотрите на этот pastie.org/1272963, который имеет правильный javascript Прямо сейчас вставка имеет at=1, поэтому ошибка будет происходит с 3-й итерации. Если вы измените его на 2, вы увидите ошибку 4-й итерации.   -  person BinnyG    schedule 04.11.2010
comment
Спасибо за полный пример; это действительно помогает. Я смог запустить это и увидеть мой ответ (stackoverflow.com/questions/4090978/orbeon-insert-in-repeat/).   -  person avernet    schedule 09.11.2010


Ответы (3)


Две вещи:

Во-первых, убедитесь, что метод, используемый для инициализации вашего объекта, называется 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 в каждой строке после текстового поля).

person avernet    schedule 09.11.2010

https://gist.github.com/768034

Вот упрощенная версия той же ошибки. Когда управление становится актуальным после того, как оно становится неактуальным, метод инициализации не вызывается, что восходит к моему предыдущему наблюдению (строка xforms.js 3798).

Действия по воспроизведению

  1. Соблюдайте два предупреждения при загрузке страницы
  2. Снимите флажок
  3. Установите флажок (соблюдайте только одно предупреждение. «Инициализированное» предупреждение не отображается)

Это правильное поведение?

person BinnyG    schedule 06.01.2011
comment
Я опубликовал ответ как другой ответ вместо того, чтобы обновлять свой предыдущий ответ, так как это выглядит как другой (связанный) вопрос (где у вас нет повторения здесь. - person avernet; 08.01.2011

(Это ответ на дополнительный вопрос, опубликованный как ответ на эта страница. Хм.)

Да, это предполагаемое поведение, и я понимаю, как это может привести к путанице. Идея метода 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:button.

person avernet    schedule 07.01.2011