(Как) Можно ли получить значение UIInput через AjaxBeahviorEvent для измененного inputText - PullRequest
0 голосов
/ 05 июля 2018

Я уже некоторое время стучу головой по кажущемуся простому делу. У меня есть Primefaces <p:inputText> (как ячейка внутри <p:dataTable>), для которой, когда значение изменяется, я хотел бы получить значение в моем контроллере. Я не могу раскрыть настоящий код, только показывая его жизненно важные выдержки:

<p:column headerText="Ratkaisu">
  <p:inputText name="inpres" id="inpres" value="#{entity.resolution}">
    <p:ajax event="change" immediate="true" execute="@this inpres" render="@this"  listener="#{mainViewController.updateEntity}"/>
    <f:param value="#{entity}" name="entity"/>
  </p:inputText> 
</p:column>

"backing bean" - это мой mainViewController, который @ ViewScoped Метод получения ajax-данных внутри контроллера:

public void updateEntity(AjaxBehaviorEvent e) {

    // I can get the entity via the parameter list
    Entity entity = (Entity)FacesContext.getCurrentInstance()
        .getExternalContext().getRequestMap().get(entity);

    // The value below is always null
    Object value = ((UIInput)e.getSource()).getValue();
    ....
}

Каждый раз, когда изменяется текст (ввод фокуса из текстового поля), я получаю ajax-запрос к своему методу. Каждый раз я нахожу правильную сущность из карты запросов, поэтому <f:param> -частица, кажется, работает.

Итак, мой вопрос (или, возможно, вопросы) заключается в том, чтобы я мог прочитать вновь введенное значение InputText в контроллере через AjaxBehaviorEvent или мне нужно попробовать что-то другое (возможно, установить значение inputText для f: param)? Также проверил, что я не нашел никаких значений в requestMap на стороне сервера ...

Я также проверил, что Инспектор Chrome публикует через ajax-запросы. Я не нашел никаких доказательств того, что текст, который я ввожу в <p:inputText>, будет отправлен на сервер.

Может ли кто-нибудь осветить или дать мне несколько советов по этому вопросу?

EDIT:

Как указывалось @ melloware , я сделал пример на стороне клиента как можно более минимальным, все еще полностью работающим:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui">

<f:view>
    <h:head>
    </h:head>

    <h:body>
        <h:form id="someid">
        </h:form>

        <p:inputText id="inpresx">
            <p:ajax event="change" process="@this"
                listener="#{mainViewController.doStuff}" />
        </p:inputText>

    </h:body>
</f:view>
</html>

для MainViewController, часть doStuff:

public void doStuff(AjaxBehaviorEvent e) {
    Object val = ((UIInput)e.getSource()).getValue();
    // val is still null!
}

Даже если программа сейчас очень минимальна, значение для inputtext не передается на серверную часть. Странная вещь IMO, это то, что мне нужны эти h: form-tags для того, чтобы пример запускал ajax-запросы.

Вот как выглядят параметры запроса xhr POST, когда я передаю TestingTesting в текст ввода и нажимаю ввод (с помощью Chrome Inspector):

javax.faces.partial.ajax: true
javax.faces.source: inpresx
javax.faces.partial.execute: inpresx
javax.faces.behavior.event: change
javax.faces.partial.event: change
someid: someid
javax.faces.ViewState: -4351418361364308383:4652862949343904732

Исходя из отправляемых выше данных, похоже, что никакие текстовые данные из входного текста не передаются на серверную сторону. Что я мог сделать не так?

РЕДАКТИРОВАТЬ 2:

tldr; Фактическим решением проблемы для меня было завернуть мой стол в форму. Тег ajax не будет работать, если нет тега формы, который ОБРАТИТ его на каком-то уровне.

1 Ответ

0 голосов
/ 05 июля 2018

Вот мой полностью рабочий пример. Все, что я печатаю во входном тексте, например "привет", получается в System.out.println.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:p="http://primefaces.org/ui"
      xmlns:h="http://java.sun.com/jsf/html">

    <h:head>   
        <title>PrimeFaces Test</title>
    </h:head>
    <h:body>

        <h:form id="frmTest">

        <p:inputText id="inpresx" value="#{testView.testString}" >
            <p:ajax event="change" process="@this" listener="#{testView.doStuff}" />
        </p:inputText>

        </h:form>

    </h:body>
</html>

Java:

package org.primefaces.test;

import javax.faces.event.AjaxBehaviorEvent;
import javax.faces.component.UIInput;
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

@ManagedBean(name = "testView")
@ViewScoped
public class TestView implements Serializable {

    private String testString;

    public void doStuff(AjaxBehaviorEvent e) {
        Object val = ((UIInput)e.getSource()).getValue();
        System.out.println("Value = " + val);
    }

    public String getTestString() {
        return testString;
    }

    public void setTestString(String testString) {
        this.testString = testString;
    }
}

И мой выход Chrome:

javax.faces.partial.ajax: true
javax.faces.source: frmTest:inpresx
javax.faces.partial.execute: frmTest:inpresx
javax.faces.behavior.event: change
javax.faces.partial.event: change
frmTest: frmTest
frmTest:inpresx: stackoverflow
javax.faces.ViewState: 9209410033241115450:-5298602114910206430
...