> -----Original Message-----
> From: Craig McClanahan [mailto:[EMAIL PROTECTED]
> Sent: Monday, February 07, 2005 3:01 AM
> To: MyFaces Discussion
> Cc: Sean Schofield
> Subject: Re: Serious inherent problem with the JSF framework life cycle
> and value binding handling?
>
> On Mon, 07 Feb 2005 02:46:05 +0200, Dani Kenan <[EMAIL PROTECTED]>
> wrote:
>
> >
> > It seems quite clear that change event handlers cannot be used together
> with
> > value properties bound to request scope beans, since they will always be
> > invoked.
>
> JSF promises to keep the expressions for all value binding expressions
> that you have set, plus values that you have set directly (not using
> value bindings). If you are expecting the framework to keep the
> values that your VB expressions point at, you are expecting something
> beyond what is promised.
[Dani Kenan] My only expectation is that the value change listener fires
only when the value changes. Is that too much to ask?
How this is implemented is not the issue. I did not request the framework to
keep the value that VB expressions point at. In any case even if this is
required in order to fix the way change events are determined, it can be
kept and regarded as an implementation detail and not exposed as a general
feature of the framework.
The spec reads:
"2.5.1.3 Executing Validation
... The converted value is pushed into the component's setValue() method,
and a ValueChangeEvent is fired if the value has changed."
There is nothing in the spec which prevents a fix. It's a matter of
interpreting what "value has changed" means. I suggest the intuitive
interpretation: changed between the last and current requests.
>
> If you want to use value change events and request scope backing
> beans, you should bind the *component* into the backing bean instead
> of the *value*. This would cause the following adjustment to your
> initial example:
>
> <h:selectOneMenu id="typeName"
> binding="#{typeListPage.typeName}"
> valueChangeListener="#{typeListPage.onChangeTypeName}">
> <f:selectItems value="#{typeNameSelectItems}" />
> <h:selectOneMenu>
>
> with the following property in your bean that "typeListPage" points at:
>
> private HtmlSelectOneMenu typeName = null;
>
> public HtmlSelectOneMenu getTypeName()
> { return this.typeName; }
>
> public void setTypeName(HtmlSelectOneMenu typeName)
> { this.typeName = typeName; }
>
> In this scenario, JSF saves the value of the component across requests
> (and restores the component reference by calling setTypeName() during
> Restore View phase, so that value change events only fire if the value
> actually changes, as you expect.
>
> If you use value binding expressions, it is your application's
> responsibility to maintain the appropriate state.
>
> Craig McClanahan
[Dani Kenan] Doesn't this means that for request scoped beans with event
handler the model we must follow is that of ASP.NET?
Jsf allows you to bind to model elements (value binding) and to ui
components (component binding) where as ASP.NET allows only its version of
component binding, pumping the values between the components and a model is
the developer's job. This results in many ASP.NET applications not having a
backing model at all (and I am talking about complex applications that
should have used one).
I liked jsf idea of binding to the model better. It would be regretful if it
becomes less usable due to this limitation.
You suggest resorting to control binding whenever a change listener is
needed. However, this results in some of the ui tree components being
updated automatically and others manually. This inconsistency leads to less
clean design and much less readable code.
Developers with consistency in mind might feel better off using component
binding all along (ignoring the possibility of value binding) - thus follow
ASP.NET paradigm and end up with the same pitfalls.
Another reply to my post by Sean Schofield suggested I dump the change
listeners and use the life cycle events in a framework like Struts Shale
(which I suspect you are quite familiar with...) to determine changes and
populate model elements on my own.
Sean's solution is viable and preserves consistency. And I liked what Struts
Shale has to offer without regard to the value change issue (isPostBack flag
and prerender event to start with).
Never the less, I still cannot see why I must either move my beans to the
session, or bind to controls and not the model, or neglect event driven
programming all along in order to fix this issue of "value change events
fire without any reason".
Dani Kenan