[Seaside] Woohoo, made a list of links! Now for the next bit...

Tim Rowledge tim@sumeru.stanford.edu
Sun, 12 May 2002 19:09:39 -0700


In message <Pine.LNX.4.30.0205121214180.6171-100000@cable.beta4.com>
          Avi Bryant <avi@beta4.com> wrote:


> Right.  So you'll probably want something like this for your main page:
> 
> <table>
> <tr>
> <td>
>   <ul>
>    ...Q1, Q2, Q3...
>   </ul>
> </td>
> <td>
>   <page sea:id="questionPane">
> </td>
> </tr>
> </table>
> 
> Where <page> is the "nice embedding protocol" you should use.
That works very nicely indeed. Excellent.

> - have an inst var keeping track of the currentQuestion
> - build some kind of a QuestionView component that can be given a question
> (let's say it has a #question: method)
> - set up your questionPane to be a QuestionView that's given the
> currentQuestion, by adding this to your main page:
> 
> addBindingsTo: template
>   (template elementNamed: 'questionPane')
>     class: QuestionView;
>     set: #question toPath: 'currentQuestion'
OK, done all that and it seems to work internally but the browser page
is not updated properly - ie dumping the text of the chosen question
works but the page in the browser keeps the same text as the first time.
Tried this on several browsers on several machines.
> 
> This will have a QuestionView be displayed where the <page
> sea:id="questionPane"> is, and will call #question: with the current value
> of currentQuestion each time before displaying it.  That all make sense?
It mostly makes sense, but I still feel a little uncomfortable about the
binding stuff being able to fumble around for instvar names. Feels too
much like rape. Is there any particular reason not to keep to messages
- especially since they work ok for setting as well as getting? Apart
from anything else a single case is much easier to explain than a
precedence hierarchy!

Just to satisfy myself, I tried with the above binding as
  set: #theQuestion toPath: 'theCurrentQuestion'
and indeed it then needed methods implementing to work. So I conclude
that the first argument is passed to the element and the second to
'self'.

> 
> Now, as for displaying the intro text when no question is selected,
> you probably just want some kind of conditional in there, like:
Works fine. Can I assume that
<td>
  <span sea:id="currentQuestion.notNil=true">
     <page sea:id="questionPane">
  </span>
  <span sea:id="currentQuestion.notNil=false">
     <page sea:id="testDescriptionPane">
  </span>
</td>
would also be considered good style? (Have you been working with this
long enough to have developed serious style & practice opinions? )

> 
> Now, I don't know what you want to happen in the QuestionView when an
> answer is chosen.
I think that the thing to do is have the question check the proffered
response and somehow return true or false to the test handling page.
Anything else would require the question page knowing the test or some
other object and that seems pointless.
For randomisable multiple choice questions (most of the q's I have to
present are, but some are of the form:-
   Q - is Three
   a) greater than 2
   b) less than 4
   c) both of the above
- clearly you can't randomly reorder these and retain any meaning) I
will permute the list of potential answers before passing it to the html
method (or whatever it is that happens). I guess I'll get back the
actual answer object when choosing the hopefully-right one. Do I get the
real oop so that simply checking it against the correct answer will
work? i.e. if I provide an array with 'foo' 'bar' & 'wibble' will I get
back the same 'foo' String and thereby find that answer == the Array
at:1 ? Or what....



> Maybe you just want to send an appropriate message to
> the question object, maybe you'll want to notify your main page for some
> reason.  If you do, you can either address it directly by sending messages
> from the QuestionView to 'parent', or you can have the QuestionView take a
> block, and then bind that block to a method in the parent:
> 
> addBindingsTo: template
>   (template elementNamed: 'questionPane')
>     class: QuestionView;
>     set: #question toPath: 'currentQuestion';
>     set: #onAnswer toMethod: #answerQuestion:

> 
> The onAnswer block in the QuestionView will now invoke the parent's
> #answerQuestion: method.
Errr.... you'll have to run that one by me again I'm afraid.  I can't
work out what a block and set:toMethod: have to do with it. Given what
I thought I understood from above (the second version of my
question/theQuestion binding) I can't see why one needs anything
different to another set:toPath:.

Later.... Hmm, perhaps it's something like a method binding being
explcitly a single method name instead of the path binding trying out
everything? Let's see, yes a method binding works for set: #theQuestion
toMethod: #theCurrentQuestion ok. It should certainly be much faster
too, since #respondsTo: is very slow.
(In the path stuff you might find it worthwhile to drop the #respondsTo:
test and simply wrap the #perform: with an exception handler. If we
assume that normally users will implicitly know the proper name of a
method, this should be better. If you are expecting that normally users
will really use instvat names, maybe the order should be swapped to be
search ivars, then try methods. Perhaps path shouldn't even consider
methods, since you have explicit method related bindings?) Lastly for
this message, what/when is this #onAnswer invoked? From what I can make
of the seaside/design.html page, all the bindings are invoked each time
the page is displayed. This doesn't seem to be quite right here so
obviously I've missed something.

tim
-- 
Tim Rowledge, tim@sumeru.stanford.edu, http://sumeru.stanford.edu/tim
Useful random insult:- Lightbulb over his head is burned out.