динамическое создание идентификаторов макрокомпонентов с использованием аргументов

#zk

#zk

Вопрос:

Я пытаюсь создать две сетки, которые выполняют точно такую же функцию, без необходимости дважды дублировать код кода для сетки. Итак, я решил использовать макрокомпонент. Но я не уверен, как динамически создавать идентификаторы компонентов в макрокомпоненте. Код выполняет следующее:

Первая сетка (западная область) имеет две строки с двумя текстовыми полями. Если я добавлю «привет» в первое текстовое поле в этой сетке, то значение второго текстового поля также будет равно «привет».

Вторая сетка (центральная область) имеет две строки с двумя текстовыми полями. Если я добавлю «мир» в первое текстовое поле в этой сетке, то значение второго текстового поля также будет равно «миру»

  • Значения обоих текстовых полей в первой сетке теперь одинаковы, т.е. «привет»
  • Значения обоих текстовых полей во второй сетке теперь одинаковы, т.е. «мир»

Я создал файл zul, в котором я использую макрокомпонент следующим образом:

 <?component name="mygrid1" macro-uri="grid1.zul" inline="true"?>
<zk>
<vbox hflex="1">
  <borderlayout height="500px" width="500px">
    <west size="50%">
      <mygrid1 id="grid1" index="1" />
    </west>
    <center>
      <mygrid1 id="grid2" index="2" />
    </center>
  </borderlayout>
</vbox>
</zk>
<zscript>
  fillInDuplicateBox(String value, Textbox duplicateBox) {
    if (!"".contentEquals(duplicateBox.value))
            return;
    duplicateBox.value = value;
  }
</zscript>
</window>
 

Макрокомпонент показан ниже:

 <zk>
<vbox hflex="1">
  <grid width="300px">
    <rows>
      <row> Box 1: <textbox id="${concat("newBox", arg.index)}" onChange="fillInDuplicateBox(${concat("newBox, arg.index)}.value, ${concat("duplicateBox", arg.index)})" hflex="1" /></row>
      <row> Box 2: <textbox id="${concat("duplicateBox", arg.index)}" hflex="1" /></row>
    </rows>
  </grid>                   
</vbox>
</zk>
 

Я также попробовал следующий код для создания макрокомпонента

 <zk>
  <vbox hflex="1">
    <grid width="300px">
      <rows>
         <row> Box 1: <textbox id="newBox${arg.index}" onChange="fillInDuplicateBox(newBox${arg.index}.value, duplicateBox${arg.index})" hflex="1" /></row>
         <row> Box 2: <textbox id="duplicateBox${arg.index}" hflex="1" /></row>
      </rows>
    </grid> 
  </vbox>
</zk>
 

Ничего из этого не работает. Я не уверен, как динамически создавать идентификаторы компонентов в макрокомпоненте. Идентификаторы текстовых полей первой сетки должны быть «newBox1», «duplicateBox1», а идентификаторы текстовых полей второй сетки должны быть «newBox2», «duplicateBox2»

Пожалуйста, укажите, есть ли лучший способ решения этой задачи.

Спасибо, Sony

Ответ №1:

Я не уверен, возможно ли динамически создавать подобные идентификаторы, но я почти уверен, что было бы лучше этого избежать. Есть лучшие способы сделать это, полностью избегая проблемы с идентификатором и вместо этого используя привязку данных или обработку событий. Ваш пример показывает, что основной целью каждой сетки является копирование значения одного текстового поля в другое текстовое поле — я полагаю, что вы пытаетесь достичь чего-то большего, поэтому дайте нам знать, приведет ли этот ответ вас к тому, что вам нужно, или нет.

Я упростил и расширил ваш образец, чтобы привести два примера, первый использует OnChanging для немедленного копирования при вводе. Вторая пара блоков использует привязку к данным.

 <?component name="mygrid1" macro-uri="/grid1.zul" ?>
<zk>
   <window>
      <vbox hflex="1">
         <mygrid1 id="grid1" myGridTitle="First" />
         <mygrid1 id="grid2" myGridTitle="Another" />
      </vbox>
   </window>
</zk>
 

Вот макрокомпонент в grid1.zul:

 <zk>
   <zscript><![CDATA[
   String myBoundString = "initial value";
]]></zscript>
   <vbox hflex="1">
      <grid>
         <rows>
            <row>
               <hbox><label value="${arg.myGridTitle}" /> Source</hbox>
               <textbox id="originalText" hflex="1" onChanging="duplicateText.value = event.value" />
            </row>
            <row>
               <hbox><label value="${arg.myGridTitle}" /> Source copies here:</hbox>
               <textbox id="duplicateText" hflex="1" />
            </row>
            <row>
               Bound to myBoundString:
               <textbox id="boundText1" value="@{myBoundString}" hflex="1" />
            </row>
            <row>
               Bound to boundText1:
               <textbox id="boundText2" value="@{boundText1.value, load-when=boundText1.onChange}" hflex="1" />
            </row>
         </rows>
      </grid>
   </vbox>
</zk>
 

В примере привязки данных вам необходимо изменить «начальное значение», а затем убрать табуляцию, прежде чем связующее обновит boundText2. Также обратите внимание, что текстовые поля имеют идентификаторы (boundText1 и boundText2), но это никак не влияет на достижение ожидаемой функциональности в нескольких экземплярах макрокомпонента.