[Twisted-web] Trouble chaining Javascript module calls in Athena (example code attached).

Jean-Paul Calderone exarkun at divmod.com
Wed May 30 11:12:32 EDT 2007


On Wed, 30 May 2007 17:53:11 +0300, kgi <iacovou at gmail.com> wrote:
>On Wednesday 30 May 2007 15:15:56 Jean-Paul Calderone wrote:
>
>Hi Jean-Paul; thanks for your email - very helpful.
>
>> Widgets on the client have a hierarchical relationship with each other
>> which reflects the hierarchical relationship of their corresponding
>> server-side LiveElement progenitors.  That is, if LiveElement B has
>> setFragmentParent called on it with LiveElement A as an argument, then
>> Widget B will have a widgetParent property which refers to Widget A;
>> similarly, Widget A's childWidgets array property will include widget B.
>> These relationships can be used to pass messages between widgets in the
>> browser without involving the server.
>
>Yep, I see the attributes for traversing along the hierarchy. Unless I've
>misunderstood, in order for a widget's Javascript to be able to call another
>widget's Javascript, it has to do something like:
>
>  self.widgetParent.widgetParent.widgetParent ...
>childWidgets[0].childWidgets[1].doStuff()
>
>This feels somewhat wrong, partly because of fragility: if I move the location
>of a widget in the hierarchy, its Javascript code will need updating.
>

Yep.  One solution to this is to do something like:

    self.widgetParent.doStuffToSpecificThing()

Supplying an implementation of doStuffToSpecific for whatever the widget's
parent happens to be which knows about its position in the overall page
layout.  This keeps the inter-widget dependency limited to a single step.

>Is there a way of accessing another widget in the page directly by name? An
>example might be a panel where I want any widget to be able to append status
>messages.
>
>I would imagine this might entail assigning a user-controlled widget id to the
>top-level DOM node of a LiveElement (as opposed to *subnodes* of the widget,
>in which ids are rewritten for use by nodeById(), and which need the athena
>id to access).
>
>I suppose the stan would look like this (this doesn't work, because the id
>gets clobbered by the autogenerated id):
>
>    T.div ( _id = 'my-unique-id', render = T.directive ( "mywidget" ) ),
>    T.div ( _id = 'another-unique-id', render = T.directive ( "mywidget" ) )
>
>Then in JS code of another widget:
>
>    w = self.getAthenaWidgetByName ( 'my-unique-id' );
>    w.doStuff()
>
>Obviously, the LiveElement nodes are already all assigned a unique id, it's
>just that it's done automatically and there's no obvious way of getting at
>them ahead-of-time.
>
>I guess I could always cheat and wrap all LiveElements inside named divs and
>do document.getElementById(), but that feels silly, given that the divs are
>already named.
>
>There are plenty of methods in Nevow/nevow/js/Nevow/Athena/__init__.js for
>getting hold of things but they all seem to need either the *numeric* athena
>id (fromAthenaID, callByAthenaID) or a reference to a node (athenaIDFromNode,
>athenaClassFromNode).
>

Something about this approach rubs me the wrong way.  Identifiers which are
required to be globally unique sends one down the path of being limited to
only supporting certain page configurations.  Maybe if there were some well
defined algorithm for choosing the "nearest" widget with a given identifier,
something could be worked out.  I'm not too sure about this either, though.

You can already do something like this, though, if the class name is a
sufficient identifier for the widget you want (find the node with the right
value for athena:class, then find the widget associated with the node).
I tend to discourage this approach in favor of the one I gave at the top
of the message, though.

Jean-Paul



More information about the Twisted-web mailing list