h: inputText внутри ui: ретранслятор отображает неправильное значение после обновления ajax - PullRequest
2 голосов
/ 13 августа 2011

У меня есть страница JSF с тегом ui: repeater, который просто отображает список строк и некоторые элементы управления для добавления строки в список. При добавлении строки я использую ajax для обновления тега повторителя, чтобы новая строка отображалась немедленно без обновления страницы. Вот как выглядит моя страница:

<h:body>
    <h:form>
        <p:inputText id="name" value="#{testController.newString}"/>
        <p:commandButton value="Add" actionListener="#{testController.addString}" update="strings" />
    </h:form>       

    <h:panelGroup id="strings">         
        <ui:repeat var="str" value="#{stringModel.strings}" varStatus="stringData">                                                                                                             
            <div>                                       
                <h:outputText value="#{str}" />
                <h:inputText value="#{str}" />
            </div>                                                                                  
        </ui:repeat>
    </h:panelGroup>                              

</h:body>

Все работает, кроме компонента inputText. После обновления UI-Repeater с помощью Ajax по-прежнему отображается текст из предыдущей строки. Например, предположим, что изначально у меня есть список с 2 строками: «val1» и «val2». Я ввожу новую строку с именем «val3» и отправляю форму. Список обновляется корректно на стороне сервера, а ретранслятор обновляется, теперь он имеет 3 элемента. Однако, хотя h: outputText во вновь добавленном элементе будет правильно показывать «val3», inputText будет отображаться с «val2» в качестве значения. В итоге я получаю что-то похожее на это:

output tag     input tag
val1           val1
val2           val2
val3           val2 (???)

Бобы основы очень просты: Модель фасоли с областью обзора

@Component
@Scope("view")
public class StringModel {

    private List<String> strings = Lists.newArrayList("Value 1");

    public List<String> getStrings() {
        return strings;
    }

    public void setStrings(List<String> strings) {
        this.strings = strings;
    }   
}

И боб контроллера области действия запроса:

@Component
@Scope("request")
public class TestController {

    private String newString;
    @Autowired private StringModel model;

    public void addString() {
        model.getStrings().add(newString);
    }

    public String getNewString() {
        return newString;
    }

    public void setNewString(String newString) {
        this.newString = newString;
    }   

}

Я провел некоторое тестирование, и это фактически работает одинаково для любого входного компонента, будь то textInput, textArea и т. Д. Любая помощь будет принята с благодарностью.

Ответы [ 3 ]

6 голосов
/ 13 августа 2011

Я не могу подробно рассказать, почему после обновления отображается неправильное значение (будет так, что индекс внутреннего цикла <ui:repeat> не работает & mdash; попробуйте более новую версию Mojarra), но я просто ссылаюсь на строковый элемент по индексу от varStatus работает. Это также немедленно решит будущую проблему невозможности передать отредактированное строковое значение, когда вы поместите этот список в форму, потому что класс String является неизменным и не имеет установщика.

<ui:repeat value="#{stringModel.strings}" var="str" varStatus="loop">
    <div>
        <h:outputText value="#{str}" />
        <h:inputText value="#{stringModel.strings[loop.index]}" />
    </div>
</ui:repeat>
2 голосов
/ 13 августа 2011

EditableValueHolders внутри пользовательского интерфейса: повтор не работает (по замыслу) в текущей версии o спецификации JSF.Это не будет работать, нет способа это исправить.Возможно, новые версии сделают пользовательский интерфейс: повторить правильный компонент с поддержкой сохранения состояний его дочерних элементов.Возможно, нет.

Если вы измените ui: повторите на h: dataTable, все должно работать (если нет, то ваша проблема где-то еще, и я ошибся).Обходной путь, кроме использования ретрансляторов из некоторых других библиотек - вы можете найти рабочие репитеры в Томагавке, Тринидаде и многих других местах.Primefaces, AFAIR, не имеет чистого повторителя.

0 голосов
/ 03 февраля 2013

У меня тоже раньше была точно такая же проблема.Я решил это, поместив inputText в форме.Я также скопировал ваши коды и поместил h:inputText в h:form, и он также работал.

...