[cells-devel] Re: Question about Cells; defobserver for both I and O
Ken Tilton
kentilton at gmail.com
Fri Jun 9 16:14:59 UTC 2006
Lars Rune Nøstdal wrote:
> Hi Lispers,
> Ok, starting to get the hang of this, but I'm having a small issue
> maybe you guys could help me with.
>
> I'm playing with some AJAX-stuff and .. hm .. not sure how to explain
> this proper, but ..
Fair warning: I have never programmed a Web app, barely done anything
with HTML, and understood almost nothing of what you wrote. :) But this
(check me: input form field initialized from a database record field,
then overwritten by user so data must flow the other way back to the
DB?) happens all the time in standalone apps, so...
>
> I have an INPUT-element (HTML) that can be used for both input of data
> (client-initiated) and output of data (server-initiated), and I'd like
> to block the observer so it does not react on input from the client and
> tries to re-update the element ..
>
> ..or maybe "blocking" the observer isn't right at all, maybe I'm going
> about this the wrong way..?
As I said, this comes up all the time, and what you tried is the
tempting automatic flow:
DB(existing value -> Input(as initial value) -> DB(new value)
Your code is what I think about writing even after ten years of using
Cells. So how do we break the cycle? There are several ways I have
handled this.
1. In the slot definition, specify:
(value ...etc... :unchanged-if 'string=)
You will still make the return trip to set the input field
unnecessarily, but that will be an NOP because the new value will be
seen as unchanged, stopping propagation (including calling observers).
The default test is EQL and it is easy in even simple code for 'string=
but un-EQL strings to arise and start cycling.
To avoid even the beginnings of a roundtrip, hey, have the observer take
a peek at where it is about to write and decide if it needs to. Not as
much fun as letting Cells worry about it, but this one observer (I
gather) is handling all the HTML input fields, so...?
Now I revert to my earlier disclaimer about being Web-ignorant: I think
The Right Answer overall will be decided by the exact nature of the Web
stuff, so I will just continue dumping alternatives
2. Does the DB flow to the form only when the form is opened? If so, the
HTML input fields can have a something another Cells user just
requested: a rule that runs once at initialization time and then becomes
a /Cells/ input. ie, the slot starts as c-formula but then becomes
c-input. (No dependencies are recorded during the initial rule
invocation.) Only the HTML input field has an observer writing back to
the corresponding DB field. Now if only cells had some frickin decent
doc I could tell you the syntax. Maybe:
(c-formula (:inputp t)
<code to lookup value for this field>)
If that is what you settle on and it does not work I will research further.
3. if you are in a multi-user environment or for any other reason need
to update the form programmatically at the same time the user is typing,
well, things will be pretty exciting for the user <g>, and it may be
time to consider the failsafe: do not try to use Cells dataflow where
the application really needs to decide the dataflow. An application flow
will have to be concocted, hopefully facilitated by Cells, but always
keep in mind that the functionality might dictate more savvy than the
Cells changed/not-changed propagation smarts.
hth, ken
> Here is some code:
>
>
> (defobserver value ((value-attribute ValueAttribute))
> (cells::trc "ValueAttribute changing from" old-value :to new-value)
> (terpri)
> ;; Update the value-attribute of the HTML-element on the client-side.
> (setAttribute (parent-of value-attribute)
> (name-of value-attribute)
> "value"
> (princ-to-string (value-of value-attribute))))
>
> (defmethod onkeyup ((value-attribute ValueAttribute) (parent Container)
> &rest event-args)
> (format t "onkeyup: ~A~%" (fifth event-args))
> (setf (value-of value-attribute)
> (first event-args)))
>
>
> `onkeyup' is called from the client-side and since (setf value-of ..)
> triggers the observer for the slot `value', it tries to "redraw" what's
> already on the client-side.
>
--
Cells: http://common-lisp.net/project/cells/
"I'll say I'm losing my grip, and it feels terrific."
-- Beaming husband to scowling life, New Yorker cartoon
More information about the cells-devel
mailing list