On Fri, Jan 21, 2022 at 12:56 AM Jonathan Meijer <jonny.mei...@gmail.com>
wrote:

> Hi,
>

Hi!


> New Tapestry user here, started with a bootstrapped 5.7.3 and
> experimenting.
>

Welcome to Tapestry! We just released 5.8.0, by the way.


>   <t:actionlink t:id="delete" context="test">Delete</t:actionlink>
>

I suggest using EventLink instead of ActionLink. Very similar, but easier
and more elegant to use.

<t:eventlink event="delete" context="test">Delete</t:eventlink>

Object onDelete(...) { ... }


>   What am I doing wrong?  There is really no room for error, the Blah class
> is defined right there in the same class and the current row object has
> absolutely no reason to be converted to String.
>

You passed an instance of Blah as the context of an ActionLink. This
component needs to know how to convert Blah to a string to be put in the
link's URL and how to do the conversion back so Tapestry can provide the
Blah instance to be passed to the event handler method when you click the
link. This is done by implementing the ValueEncoder instance for your class
then contributing it to the ValueEncoderSource service. Internally, when a
ValueEncoder isn't found for a given type, Tapestry tries to fallback on
using a coercion from String to type and type to String from the
TypeCoercer service. That's why I'm suggesting ValueEncoder and Voker is
suggesting a coercion and both solutions are valid. :) I just prefer the
ValueEncoder route in this case because it's specific for URLs (including
page activation context, event handler parameters, etc) and TypeCoercer is
more general-purpose conversions, specially for component and page
parameters (for example, Grid's source parameter receives a GridDataSource
but you can pass a List to it).

Example of ValueEncoder usage:

public class BlahValueEncoder implements ValueEncoder<Blah> {
    public String toClient(Blah value) {
        (...)
    }

    public Blah toValue(String clientValue)
    {
        (...)
    }
}

In AppModule:

    public static void
contributeValueEncoderSource(MappedConfiguration<Class, Object>
configuration) {
        configuration.add(Blah.class, new BlahValueEncoder()); // or, with
dependency injection: configuration.addInstance(Object.class,
BlahValueEncoder.class);
    }



>
> Kindly help,
>
> Jonathan
>


-- 
Thiago

Reply via email to