tarsis
tarsis

Reputation: 174

Tapestry - how to get other component's field

I have a tapestry class which loads a variable

public class Component1 {
    Object onActionFromEdit(MyClass object){
        String param = object.getMyParam();
    ...}
}

I would like to access the param value from other component.

What is the best way to get it? Is there some common context where I could store variables? I tried to search the documentation but had no luck so far.

Upvotes: 1

Views: 388

Answers (2)

Dmitry Gusev
Dmitry Gusev

Reputation: 891

Difficult to guess, but judging by the name onActionFromEdit may be event handler for EventLink where parameter is passed in HTTP GET request as a query param.

If that's the case there are several ways of sharing event context with other components/parts of the app:

  1. Component parameters - they are actually bi-directional bindings, assigning parameter field from component will write the value to where the parameter was bound. Of course the value will only be available in the scope of current request unless either the fields or associated bindings were annotated with @Persist

    class Component1 {
       @Parameter MyClass param1;
    
       onActionFromEdit(MyClass object) {
            param1 = object; // this will update value of a binding
                             // where this parameter is set
       }
    }
    
  2. If you want to share state with parent component, then you could also @InjectComponent Component1 component1 in parent and access its state directly as with regular java objects, e.g. component1.getState1(), of course this has to be done after event handler assigned the value from request.

  3. Environmental services. This is a per-request service, it's often user by parent components pushing state for child/nested components during rendering/event handling, e.g. t:Form and t:TextField.

  4. It's always possible to create a dedicated per-thread service for concrete use-case and @Inject it where needed. The service may hold shared state in own fields, it will be discarded at the end of the request. The service may also register a cleanup listener in case you need custom logic for end of request cleanup.

Again, difficult to tell why you need this/what's your use-case, but Tapestry pages support activation contexts. Each event link will have this context transparently added, so each time event link is called, containing page will be activated with the stored context and it's then possible to publish this state for components, e.g. using regular component parameters, or one of the methods mentioned above. Jumpstart examples for onActivate/onPassivate.

It's also worth mentioning the @ActivationRequestParameter, you can find more usage examples in the JumpStart.

There's also Session Storage if you need to capture data and share it with other parts of the app in multiple requests. But it sounds too much for your question.

There are other, non-tapestry, ways of sharing data that also work in Tapestry apps, e.g. request attributes, query parameters, etc. But you normally don't use them.

Upvotes: 1

joostschouten
joostschouten

Reputation: 3893

I think you are looking for the ComponentResources class which will allow you to do the following:

public class Component1 {

    @Inject
    private ComponentResources resources;
    
    Object onActionFromEdit(){
        MyComponent comp = (MyComponent) resources.getEmbeddedComponent("ComponentId");
        String param = comp.getMyParam();
    }
}

If the component is not embedded but part of a sibling, you can also resources.getContainerResources().getEmbeddedComponent("ComponentId") or even fetch it from the page like so: resources.getPage().getComponentResources().getEmbeddedComponent("ComponentId")

Upvotes: 0

Related Questions