Componentes JSF com problemas de atualização

9 respostas
Danilo_Marchiori

olá,
desenvolvi alguns componentes em jsf 1.1 e agora estou usando-o em dois projetos. Em um projeto também jsf, o componente se comporta de maneira esquisita, ele é acessado uma primeira vez pelo usuário e todas as outras vezes em que é renderizado novamente ele renderiza o estado anterior.
Por exemplo, tem um componente que monta uma tabela dado alguns dados de entrada vindos de um banco. Mesmo com a mudança desses dados no banco, a próxima vez que esse componente é renderizado na mesma página, é mostrado o estado da vez anterior, ou seja, dados antigos.
Debugando, reparei que depois da primeira renderização, o o método setproperties não é mais chamado… isso é ruim. Olhando o ciclo de vida do jsf isso também não me parece correto. Testei com e sem formulários e também não obtive sucesso.

Alguem tem alguma idéia do problema? Já passou por algo parecido?

9 Respostas

urubatan

na verdade parece que tu que não entendeu muito bem :smiley:
o setProperties tem que criar bindValues e estes serão lidos todas as vezes que o componente for renderizado :smiley:

se foi isto que tu fez, ai tu vai ter que mostrar parte do código para vermos o que pode estar errado :smiley:

Danilo_Marchiori

Sei que o setProperties liga as propriedades do meu componente à propriedades passadas pela Tag, que podem estar em ActionForm ou em um backing bean.
O problema acontece mesmo eu mudando os valores desses parâmetros do componente o resultado exibido é sempre o mesmo.
Debugando eu vejo o método setProperties sendo chamado na primeira renderização, é a única vez que ele é chamado. Da segunda em diante, mesmo quando os valores passados são diferentes (por exemplo um objeto resultSet) o componente renderiza os valores da primeira vez… entendeu?

Danilo_Marchiori

Eu observei outra coisa…
quando eu entro numa página, o backing bean é inicializado (o método construtor é chamado), nele os valores de entrada para o componente são recuperados (de uma banco por exemplo).
Quando eu dou um refresh na página o método construtor não é chamado novamente.
Só consegui fazer o método construtor ser chamado novamente quando eu coloco mais de um <f:view> na página.

Muito estranho… será que eu estou usando errado o componente? O backing bean não deveria ser chamado novamente a cada carregamento da página?

urubatan

posta aqui o teu setProperties, e também a parte do teu componente que le o valor pra eu ver o que pode estar errado.

Danilo_Marchiori

setProperties

Dentro do componente tem um atributo chamado viaTable. Os valores são passados por esse atributo, ou seja, no projeto onde é usado esse componente é criado um objeto do tipo VIATable... isso dentro de um backing bean ou de um Action (se eu usar o componente jsf dentro de um projeto struts). Esse objeto criado é passado para o componente através de um atributo da tag chamado bind.

protected void setProperties(UIComponent component)
    {
        super.setProperties(component);

        VIATableClass viaTable = (VIATableClass) component;
        Application app = getFacesContext().getApplication();
		
        if(id != null)
        {
            component.setId(id);
            viaTable.setId(id);
        }
		
        if(bind != null)
        {
            if (isValueReference(bind))
            {
                viaTable.setValueBinding("viaTable",app.createValueBinding(bind));


                FacesContext context = FacesContext.getCurrentInstance();
                app = context.getApplication();
                ValueBinding vb = app.createValueBinding(bind);
                //viaGraph.getSequenceItemList().setValueBinding("sequenceItemList", vb);
                Object v  = vb.getValue(context);
                viaTable.getAttributes().put("viaTable", v);
            }
        }

	}

Mas tem outro lance, em um projeto jsf, quando eu dou refresh na página o construtor não é chamado depois da primeira vez. Isso não deveria acontecer??

urubatan

não ddeveria não, quer dizer …
e você esta escrevendo componentes como se fossem tags simples MVC, componentes JSF são como componentes swing, então tu ta fazendo tudo errado :smiley:
a tag não tem que pegar o valor do parametro como tu ta fazendo em:
viaTable.getAttributes().put(“viaTable”, v);

o que tu tem que fazer é:

ValueBinding vb = context.getApplication().createValueBinding(value);

component.setValueBinding(propName, vb);

ou seja, tem que passar o value binding pro componente, e não o valor no momento em que é chamado o setProperties

e no getter do componente tu faz mais ou menos isto:

public String getEnabledOnUserRole()

{

if (_enabledOnUserRole != null) return _enabledOnUserRole;

ValueBinding vb = getValueBinding(“enabledOnUserRole”);

return vb != null ? _ComponentUtils.getStringValue(getFacesContext(), vb) : null;

}

ou seja, sempre usa o getter, e no getter sim tu pega o valor do binding que foi passado.

tradução, não é um problema do JSF, é um problema do teu componente como foi escrito :smiley:

da uma olhada no código dos componentes do tomahawk para pegar uns exemplos de como fazer componentes …

isto é devido ao late binding que os componentes JSF precisam ter …

Danilo_Marchiori
Comecei a entender o late binding…

No setProperties quando vc faz o binding desse jeito

viaTable.getAttributes().put(“viaTable”, v);

o valor recuperado é uma cópia q sempre será usada nas próximas vezes. Mas quando vc faz

component.setValueBinding(propName, vb);

o valor é “linkado” com o objeto de onde está sendo usado o componente… como se fosse um único objeto que só o cliente altera. dai no getter sempre é recuperado esse binding… isso mesmo?

No seu código o que eu não entendi foi o
return vb != null ? _ComponentUtils.getStringValue(getFacesContext(), vb) : null;

Onde vc buscou esse _ComponentUtils??

Danilo_Marchiori
Em vez de

return vb != null ? _ComponentUtils.getStringValue(getFacesContext(), vb) : null;

substitui por

return (VIATable) (vb != null ? vb.getValue(getFacesContext()) : null);

onde VIATable é o meu tipo.

Essa é a idéia?

R

Exatamente!!!

Criado 6 de setembro de 2006
Ultima resposta 3 de out. de 2007
Respostas 9
Participantes 3