Переменная области итерации в итерации JSF / Richfaces? - PullRequest
4 голосов
/ 27 января 2011

ОК, это должно быть интересно, я думаю.Я хочу минимизировать количество вызовов для моего компонента Seam внутри итерации.Я использую Seam 2.2.1.CR1, Richfaces 3.3.3.Final, JSF 1.2 и Facelets.

Пожалуйста, посмотрите следующий фрагмент Facelet:

<rich:datatable value="#{myBean.products}" var="prod">

<rich:column rowspan="#{rowspan.calcHomePageProductRowspan(prod)}">
    #{prod.name}
</rich:column>

<rich:column rowspan="#{rowspan.calcHomePageProductRowspan(prod)}">
    #{prod.number}
</rich:column>

...

<rich:column rowspan="#{rowspan.calcHomePageProductRowspan(prod)}">
    #{prod.somethingElse1}
</rich:column>

<rich:column rowspan="#{rowspan.calcHomePageProductRowspan(prod)}">
    #{prod.somethingElse2}
</rich:column>

...

<rich:column rowspan="#{rowspan.calcHomePageProductRowspan(prod)}">
    #{prod.somethingElse3}
</rich:column>

</rich:datatable>

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

Я произвел внутреннюю оптимизацию в компоненте rowspan Seam, и он сохраняет в HashMap все уже вычисленные значения.за продуктами.Таким образом, когда выражение EL вычисляется во втором rich:column, rowspan сначала ищет в HashMap уже вычисленное значение и возвращает его, вместо того, чтобы заново вычислять все заново.

Хотя это лучше, чем пересчитывать все заново, мне все равно придется вызывать компонент Seam.Есть ли способ как-то вызвать компонент Seam только один раз и как-то сохранить вычисленное значение для текущей итерации?

По аналогии с Java можно было бы определить переменную внутри цикла на каждой итерации и использовать ее повторно.на протяжении всей итерации.

Примечание: Я уже провел другие Seam-ориентированные оптимизации, такие как @BypassInterceptors, компонент Seam находится в области EVENT, поэтому иерархический поиск не проводится и т. д.

1 Ответ

1 голос
/ 27 января 2011

Есть ли способ каким-либо образом вызвать компонент Seam только один раз и каким-то образом сохранить вычисленное значение для текущей итерации?

Конечно, в теории.

Но я не уверен, что полностью понимаю ваш вопрос.О каком компоненте шва вы говорите?rowspan?

Если это так, то да, он вызывается каждый раз, когда вы его называете, что имеет смысл.Вы перебираете dataTable, и для каждой строки вы называете его.

Не зная больше деталей о том, что вы пытаетесь сделать, трудно предложить ответ.Код медленный?Поэтому вам нужно оптимизировать дальше?

Обновление

Попробуйте, хотя я не уверен, работает ли он

<rich:dataTable value="#{myBean.products}" var="prod">
   <ui:param name="myrowspan" value="#{rowspan.calcHomePageProductRowspan(prod)}"/>
   <rich:column rowspan="#{myrowspan}">
     #{prod.name}
   </rich:column>
</rich:dataTable>

Второе обновление

Таким образом, если вы не измените свой код на @Out, @Factory, @Unwrap или аналогичный, то он всегда будет оцениваться при каждом запуске.Так работает JSF.Вот почему они говорят, что вы должны делать это в своих получателях, потому что JSF будет вызывать это для каждой фазы JSF.

public List<Foo> getFoo() {
  if(this.field != null) { 
    field = (List)entityManager.createQuery("from Foo").getResultList();
  } 
  return this.field; 
}

Если бы вы не кэшировали список и проверяли на ноль, JSF нажалбаза данных для каждой фазы и для каждой строки в таблице данных.

Таким образом, это просто то, с чем вам придется жить.

...