Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > JSF: проблема с custom tag-ом


Автор: trace 22.2.2006, 17:15
добрый день,

возникла следующая проблема.
разработан некоторый jsf custom tag. он функционирует корректно, если его поместит просто в форму, но если его поместить в PanelGrid, то при сабмите формы(по кнопке либо javascript-ом), он отображается 2 раза. еще раз сабмитишь - 3 раза. еще раз - 4, и т.д. , и т.п.
Может кто-то подскажет, в чем может быть проблема?

Автор: alexsmirnov 28.2.2006, 22:54
Скорее всего, в методах saveState/restoreState забыли сохранить или восстановить состояние суперкласса
то есть скорее всего проблемы в изменении id компонента между запросами

Автор: trace 1.3.2006, 12:44
У меня вообще не были переопределены saveState() и RestoreState(). Но добавление их в виде
Код

 public Object saveState(FacesContext context)
    {
        Object[] values = new Object[1];
        values[0] = super.saveState(context);

        return values;
}
    public void restoreState(FacesContext context, Object state)
    {
        Object[] values = (Object[])state;
        super.restoreState(context, values[0]);
    }


ничего не изменило, к сожалению. Id компонента я получаю через String clientId = getClientId(context), при сабмите EncodeBegin вызывается несколько раз, и id при этом выдается тот же самый. Может в Save/RestoreState нужно добавить что-то еще?

Автор: alexsmirnov 4.3.2006, 13:25
Тогда нужно более подробно про код для понимания.
Разница с PanelGrid - он сам выводит дочерние компоненты, вместо вывода по тегам JSP.
Когда встречается такое место - jsf пытается понять - остались ли компоненты старыми ил что-то на странице поенялось ( например- сработал <c:if >
Для сравнения используются именно id компонентов, и если они не сохраняются ( после восстановления null ) - именно такое дублирование и происходит.
Но это не единственная причина , возможны варианты
Попробуй присвоить компоненту id в явном виде - если опять продублируются и не будет exception на duplicate id - ищи именно в этом направлении
Если выругается - скорее где-то в JSP теге

Автор: trace 10.3.2006, 14:30
Id у меня и задается напрямую, это необходимый атрибут... в общем, думаю, лучше привести код:

на jsp странице (неотносящиеся к делу атрибуты опущены)
Код

 <ct:customerSelectTag  id="customerID"/>


UICustomerSelectTag(лишнее тоже опущено, основная идея в том, что ид берется из getClientId,
и используется как id input-а):

Код

public class UICustomerSelectTag extends UIInput {

    public UICustomerSelectTag(){
        super();
        this.setRendererType(null);
    }

    public String getFamily() {
        return null;
    }

    public Object saveState(FacesContext context)
    {
        Object[] values = new Object[1];
        values[0] = super.saveState(context);

        return values;
}
    public void restoreState(FacesContext context, Object state)
    {
        Object[] values = (Object[])state;
        super.restoreState(context, values[0]);
    }

    public void encodeBegin(FacesContext context) throws IOException {
        if (!isRendered()){
            return;
        }
        ResponseWriter writer = context.getResponseWriter();
        String clientId = getClientId(context);
        String customerInputId = clientId;
        writer.startElement("input", this);
        makeWriteAttribute(writer, "value", (String)eval("value"), "value");
        writer.writeAttribute("id", customerInputId, "id");
        writer.writeAttribute("name", customerInputId, "name");
        writer.endElement("input");
    }

     public void makeWriteAttribute(ResponseWriter writer, String attributeName, 
            Object attributeValue,    String componentProperty)  throws IOException {
        if (attributeValue != null) {
            writer.writeAttribute(attributeName, attributeValue, componentProperty);
        }
     }

     public void decode(FacesContext context) {
        Map requestMap = context.getExternalContext().getRequestParameterMap();
        String clientId = getClientId(context);
        String valueName = (String)requestMap.get(clientId);
        setSubmittedValue(valueName);
        setValid(true);
      }


Вот примерно так. Можете что-то посоветовать?

Автор: trace 10.3.2006, 15:31
Еще один момент. Эта проблема 100% связана именно с заданием id тега, потому что в отсутствие этого атрибута удваивание не происходит. Однако, проблема в том что мне по функциональности никак без задания ид не обойтись...

Автор: trace 13.3.2006, 19:43
В общем(может кому пригодится), проблема была таки в задании атрибута id для custom tag-а. Мне нужно было задавать id (фактически было несколько custom tag-ов, используемых в связке). Наверное, jsf как-то иначе анализирует теги при задании именно атрибута id... Anyway, заменой атрибута id на атрибут customerID(можно подставить что угодно smile) проблема была решена smile. Больше никакого удваивания, утраивания и пр., чего и всем желаю smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)