2013-04-22 3 views
4

В модуле заказа на поставку нам нужно задать определенные вопросы в зависимости от метода выбора источника, типа конкурса и общей стоимости ПО. Эти вопросы, вероятно, будут меняться со временем и между различными экземплярами базы данных.Динамическое связывание в режиме повторного управления

Поэтому у меня есть представление, содержащее вопросы, так что я могу динамически добавлять вопросы в свой XPage, не меняя код. Ответ на каждый вопрос будет сохранен в поле. Таким образом, документ, содержащий этот вопрос, имеет поле FieldName, которое используется для предоставления имени поля, которое будет использоваться. К сожалению, мне не повезло связать эти динамические поля с документом.

<xp:this.data> 
    <xp:dominoView var="competitionQuestionView" 
     viewName="CompetitionQuestions"> 
    </xp:dominoView> 
</xp:this.data> 
<xp:repeat id="repeat2" rows="30" var="rowData" style="width:700px" 
    value="#{competitionQuestionView}"> 
    <xp:label id="label1"> 
     <xp:this.value><![CDATA[#{javascript:rowData.getColumnValue("Question");}]]></xp:this.value> 
    </xp:label> 
    <xp:inputText id="inputText1"> 
     <xp:this.rendered><![CDATA[#{javascript:rowData.getColumnValue("FieldType") == "Text Box"; }]]></xp:this.rendered> 
     <xp:this.value><![CDATA[#{javascript:poDoc[rowData.getColumnValue ("FieldName")];}]]></xp:this.value> 
    </xp:inputText> 
</xp:repeat> 

Я пробовал различные способы, чтобы сделать это, в том числе делая dynamicInputText пользовательский элемент управления, чтобы передать имя поля, но без удачи. Ближайший я получил, когда я использовал это:

<xp:this.value> 
<![CDATA[#{javascript:tmp = rowData.getColumnValue ("FieldName");'#{poDoc.'+tmp+'}';}]]> 
</xp:this.value> 

Это дало мне что-то вроде # {} poDoc.justification, что было то, что я хотел передать в «связывания», но в конечном итоге, как отображение текстовое значение.

Я попытался использовать $, чтобы вычислить значение при загрузке, но я предполагаю, что это не сработало, потому что мой (и rowData) вид недоступен при загрузке. В конечном итоге это создаст проблему, когда я захочу использовать частичные обновления из-за обновлений по критериям, полям которых я хочу отобразить в любом случае.

Некоторые ответы на другие вопросы выглядели многообещающими, но код не был предоставлен, поэтому я не мог понять это.

ответ

10

За кулисами все источники данных используют методы getValue и setValue (соответственно) для чтения и записи данных. В случае источника данных документа Domino выражение #{currentDocument.fieldName} преобразуется во время выполнения в currentDocument.getValue('fieldName') или currentDocument.setValue('fieldName', postedValue), в зависимости от того, является ли текущая операция чтением или записью.

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

Другими словами, для чтения/записи для работы это должно быть «префиксное» выражение.

Существует несколько способов справиться с этим, но проще всего использовать контекст данных для сопоставления выражения SSJS с одной переменной. контексты данных могут быть присоединены к корню зрения или к панели, так что в вашем примере, вы хотите, чтобы обернуть содержимое повтора в панели:

<xp:repeat id="repeat2" rows="30" var="rowData" style="width:700px" 
    value="#{competitionQuestionView}"> 
    <xp:panel> 
     <xp:this.dataContexts> 
      <xp:dataContext var="fieldName"> 
       <xp:this.value><![CDATA[#{javascript:rowData.getColumnValue ("FieldName");}]]></xp:this.value> 
      </xp:dataContext> 
     </xp:this.dataContexts> 
     <xp:label id="label1"> 
      <xp:this.value><![CDATA[#{javascript:rowData.getColumnValue("Question");}]]>  </xp:this.value> 
     </xp:label> 
     <xp:inputText id="inputText1" value="#{poDoc[fieldName]}"> 
      <xp:this.rendered><![CDATA[#{javascript:rowData.getColumnValue("FieldType") == "Text Box"; }]]></xp:this.rendered> 
     </xp:inputText> 
    </xp:panel> 
</xp:repeat> 

Таким образом, для каждого члена повтора, переменная fieldName становится значением столбца для этой строки. Затем в атрибуте value входного компонента используется синтаксис массива (вместо обычного точечного синтаксиса), так как мы хотим использовать переменную, чтобы указать имя поля вместо hardcoding имя.

В теории, однако, вы должны быть в состоянии пропустить контекст данных целиком, а просто установить следующее как выражение значения для поля:

#{poDoc[rowData.FieldName]}

В контексте по умолчанию («prefixless») EL resolver, rowData.FieldName должен возвращать точно такое же значение, которое возвращается rowData.getColumnValue("FieldName") в контексте выражения SSJS.

Наконец, я бы рекомендовал прочитать this Expression Language tutorial, чтобы ознакомиться со всеми вещами, которые вы можете делать в основном EL, не прибегая к SSJS.

+2

+1: # {poDoc [rowData.FieldName]} будет работать. К сожалению, EL обычно недооценивают или неправильно понимают разработчики. –

+0

Как ни странно, ни сначала не работали. Я продолжал сбивать ошибку, когда bean был нулевым (с именем поля как свойство). Затем я начал работать с dataContexts, созданным путем копирования и вставки кода вместо редактирования моего. Это спасение жизни, Тим. Благодаря! –

Смежные вопросы