28 февраля 2011 г.

Глобальный контекст переменных в SSJS библиотеках

Неисповедимы пути логики IBM.
Обнаружил такой факт: переменные объявленные в SSJS библиотеке имеют глобальную область видимости для всего приложения, т.е. что-то типа applicationScope.


Приведу пример, что бы было понятнее о чем я
 - создаем библиотеку SSJS
 - в библиотеке объявляем переменную и функцию
       var Tst;

       function Init(){
           Tst = @Now();
       }

 - подключаем библиотеку к xPage в ресурсах...

По идее библиотеку я подключил к конкретной странице и код должен был-бы быть как бы часть только этой страницы, но не тут-то было.

- определяем в коде xPage эту переменную уникальным значением - на beforePageLoad вешаем вызов Init() (в той же библиотеке функция инициализации переменной)
- для теста делаем вычисляемое поле со значением из переменной (Tst), и кнопку, котороя только делает частичное обновление этого поля.
- открываем нашу страничку дважды (значения разные в поле - уникальные)
- идем в первый открытый и жмем нашу кнопку обновить - и видим что значение стало из второго документа....

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

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

Вот такой вот выверт логики...
сервер 8.5.2
Код библиотеки xTST.jss:
var Tst;

function Init(){
    Tst = @Now();
}

Код тестовой страницы:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
    <xp:this.beforePageLoad><![CDATA[#{javascript:Init()}]]></xp:this.beforePageLoad>
    <xp:this.resources>
        <xp:script src="/xTST.jss" clientSide="false"></xp:script>
    </xp:this.resources>
    <xp:text escape="true" id="computedField1"
        value="#{javascript:Tst}">
        <xp:this.converter>
            <xp:convertDateTime type="both" timeStyle="full"
                dateStyle="full">
            </xp:convertDateTime>
        </xp:this.converter>
    </xp:text>
    <xp:button value="refresh" id="button1">
        <xp:eventHandler event="onclick" submit="true"
            refreshMode="partial" refreshId="computedField1">
        </xp:eventHandler></xp:button></xp:view>

3 комментария:

Анонимный комментирует...

Андрей, скажите пожалуйста, удалось ли вам найти, как получить значения переменных, определенных в серверных библиотеках из клиентских библиотек. Например общие константы.
Я пытался использовать shared variable http://www-10.lotus.com/ldd/ddwiki.nsf/dx/xpages-scoped-variables.htm
но безуспешно.

Черепанов Андрей комментирует...

К моему великому сожелению, погрузится в xPages так что бы нарабатывать нормальный опыт пока не получается. Очень многое для меня остается загадкой в этой технологии. Но по Вашему вопросу кое что есть... :) как на прямую общатся клиенту и сервере без великих танцев с бубном, как-то не нашел\не придумал, поэтому пошел простым путем - через поля формы. есть div (Panel) в котором расположены поля для обмена, связанные со scoped переменными (серверными), у панели стиль display:none (заметьте не visible = false, а именно стиль), есть кнопка на странице, так же стилем скрытая - не размещайте ее в той же панели, что и поля для обмена - в IE огребетесь (!) - работать будет только один раз. у кнопки стоит, в настройках событий, частичное обновление нашей панели с полями "для связи". Ну в общем и всё - для передачи на сервер значений пишем в поля и кликаем кнопку. Обратно как-то так же, но тут есть подводные камни - как инициировать что-то в клиенте по событию на сервере...
Далее, "константы" можно определить следующим образом: делаем клиентскую библиотеку, в ней определяем var переменные, далее на onLoad в клиентском событии пишем определение\присваивание этих переменных. В xPages на этом событии можно подставлять "серверные" вычисления (не помню как они правильно называются) - что-то типа ClientVar = #{id:MyField} - ClientVar'у присвоится вычиленный на сервере id поля MyField. Можно и более сложные конструкции: #{viewScoped:MyVar}, #{javascript:......}
Это конечно как-то топорно, но работает... :)

Анонимный комментирует...

Андрей, спасибо за такой подробный и оперативный ответ. Я тоже пришел к выводу, что только через элементы дизайна: поля, возможно, нестандартные HTML теги. Например:
.
Может быть удастся использовать compositeData (пример на http://www-10.lotus.com/ldd/ddwiki.nsf/dx/Tutorial-Introduction-to-XPages-Exercise-2), но скорее всего, видимость свойств будет только не серверной стороне.
Еще раз спасибо :-)

Отправить комментарий