вызов метода с библиотекой jsf 2.0 ajax - PullRequest
1 голос
/ 01 апреля 2012

Я работаю над приложением, в котором пользователи будут оценивать произведение искусства и заполняют форму обзора по мере продвижения.Они могут тратить значительное количество времени на форму, поэтому я хочу сохранять ее автоматически для пользователя, скажем, каждые 5 минут.Я надеялся, что смогу использовать javascript и установить таймер на 5 минут, а затем заставить его выполнить всю форму через ajax, и я смогу сохранить данные в базе данных на случай, если пользователь отключится и т. Д. К сожалению, я не могу найтилюбой способ сделать это.Обновление модели с данными не является проблемой, но я не могу понять, как заставить ее вызывать метод (аналогично тому, как обычно поступает действие, когда оно было отправлено). Я не хочу или не нуждаюсь в этомперерисовать что угодно, просто позвольте мне вызвать метод для сохранения данных.Как я могу это сделать?

Проблемы с реализацией решения

Я пытался реализовать решение скрытой командной ссылки, но у меня очень странное поведение.Я не уверен, что является причиной этого.Во-первых, некоторые сведения о реализации.Форма # 1 создает компонент (не определен) и помещает его во флэш-память, а затем перенаправляет на форму № 2.Форма № 2 - это большая форма, о которой я писал, где я хочу реализовать автосохранение.Форма № 2 имеет компонент ViewScoped.В PostConstruct для этого компонента он получает значение из flash и заполняет поле свойства.Все идет нормально.Это прекрасно работает без JavaScript.Я могу нажать командную кнопку, чтобы отправить форму, и все хорошо.Однако, когда я представляю javascript, когда он выполняется, я получаю исключение нулевого указателя из переменной, которая должна была быть заполнена из флэш-памяти PostConstruct.Как этот javascript мешает этому?После того, как я заполнил свойство bean-объекта видимости объектом, не должно иметь значения, удален ли он из области видимости flash, верно?К вашему сведению, если я удаляю ТОЛЬКО код javascript и оставляю все остальное, он возвращается к нормальной работе, когда я нажимаю кнопку подтверждения.

Форма # 1

    <h:form>
    ... bunch of form objects ...
    <h:commandButton "Start New" action="#{someRequestScopedBean.someMethod"/>
    </h:form>

код для someRequestScopedBean.Method:

    public String someMethod() {
        // bunch of logic here
        FacesContext.getCurrentInstance()
            .getExternalContext()
                .getFlash()
                    .put("myFlashObj", myFlashObj);
        return "form2?faces-redirect=true";
    }

просмотр области действия, используемой в форме 2:

    @ManagedBean
    @ViewScoped
    public class someViewScopedBean { 
        //bunch of properties here 

        @PostConstruct
        public void initialize() {
            this.myObject = (MyObject) FacesContext.getCurrentInstance()
                           .getExternalContext()
                           .getFlash()
                           .get("myFlashObject");
        public void saveDraft() { 
            // save to database
        }
    }

Форма 2 страницы:

    <h:outputScript library="javax.faces" name="jsf.js"/>
    <h:form id="myForm">

       ... whole bunch of fields here ... 

       ... real button for user to submit ... 
       <h:commandButton value="Submit myForm" 
                        action="#{someViewScopedBean.save}" />

       ... hidden button for auto-save by javascript ... 
       <h:commandLink id="hiddenSaveDraft" style="display: none;" 
                      action="#{someViewScopedBean.saveDraft}" >
              <f:ajax execute="@form" />
       </h:commandLink> 

       <script>
           function saveDraft() {
                document.getElementById('qForm:hiddenSaveDraft').onclick();
                window.setTimeout('saveDraft()',15000);
           }
           saveDraft();
       </script>

    </h:form>

Ответы [ 2 ]

1 голос
/ 04 апреля 2012

Я выяснил окончательное решение и причину проблем, с которыми я столкнулся при его реализации в первый раз.Это было связано с тем, когда был запущен JavaScript.Код сценария запускался именно в тот момент, когда я поместил блок <script></script>, который был до полной загрузки страницы и, вероятно, до завершения DOM.Это вызывало всевозможные неприятности, включая повторяющиеся вызовы @PostConstruct.

Я исправил это с помощью прослушивателя событий javascript, который срабатывал при полной загрузке страницы.Это важно, потому что я использую шаблоны лица и у меня не было доступа к атрибуту <h:body onload=.Слушатель - это полезное и элегантное решение.Блок скрипта может быть размещен в любом месте страницы.Вот как выглядит блок скрипта:

    <script>

    function saveDraft() {
        document.getElementById('qForm:saveDraft').onclick();       
        window.setTimeout(saveDraft,300000);
    }

    function initSaveTimer(e) {
        window.setTimeout(saveDraft,300000);
    }

    this.addEventListener("load",initSaveTimer,true);

    </script>

Это будет вызывать скрытую кнопку каждые 5 минут для сохранения формы.

1 голос
/ 01 апреля 2012

Поскольку вы записали Javascript в качестве одного из своих тегов, я предполагаю, что вы включили Javascript код на стороне клиента в свое приложение.

Прежде всего используйте скрытый <h:commandButton/> илискрытый <<code>h:inputText/> (я использую последнее в тех случаях, когда мне нужно хранить некоторую информацию, касающуюся определенной переменной)

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

<h:commandButton style="display:none" id="clickme">
  <f:ajax execute="@form">
</h:commandButton>

<h:inputText style="display:none" id="changeme">
  <f:ajax execute="@form">
</h:inputText>

В коде Javascript добавьте этот код, чтобы либо щелкнуть, либо изменить:

setInterval(function() { 
  document.getElementById("clickme").onclick();

}, 3000); // update every 3 seconds

setInterval(function() { 
  document.getElementById("changeme").onchange();
}, 3000); // update every 3 seconds

Оба будут работать нормально.Просто убедитесь, что они находятся в той форме, которую вы обновляете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...