Josh, Yeah that looks like it would do it, working much like what proposed with pagelinks. Given a choice I would use the pagelink based way because architecturally it works the same (news page collects the id via context), but using pagelinks reduces the round-trips and the need to deal with events. Janos if you're still listening ;-), I think we've found the best ways possible to do what you want. The missing piece is that you said your News component was a component and not a page, so in that case use a page property (like Josh said) and in your page's template, testing for a valid newsId, provide the News component with it. These are the best methods we've seen, I just can't figure out why my mind keeps saying there's a better way :-|.
chris Josh Canfield wrote: > Here's an app that does what I believe is trying to be done: > > // Page > public class News { > @Property > private Integer _newsId; > public void onActivate(Integer newsId) { > _newsId = newsId; > } > > public Integer onPassivate() { > return _newsId; > } > } > > // Page Template > <?xml version="1.0" encoding="UTF-8" ?> > <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" > "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> > > <html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd"> > <body> > <t:newsQuote newsId="newsId" /> > </body> > </html> > > // Component > public class NewsQuote { > > @Parameter > private Integer _newsId; > > @Inject > private ComponentResources _resources; > > void beginRender(MarkupWriter writer) { > writer.element("ul"); > for (int i = 0; i < 5; ++i) { > writer.element("li"); > Link link = _resources.createActionLink("show", false, > i); > writer.element("a", "href", link.toURI()); > writer.write("News number " + i); > writer.end(); > if (_newsId != null && _newsId.equals(i)) { > writer.write(" You picked " + _newsId); > } > writer.end(); > } > writer.end(); > } > > // The Action handler > void onShow(Integer id) { > // stored into the bound parameter, feeding it back into the > page > _newsId = id; > } > } > > The url http://localhost:8080/news/4 > > Renders > > <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" > "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> > <html xmlns="http://www.w3.org/1999/xhtml"> > <head> > <link href="/assets/tapestry/default.css" rel="stylesheet" type="text/css"> > </head> > <body> > <ul> > <li><a href="/news.newsquote:show/0?t:ac=4">News number 0</a></li> > <li><a href="/news.newsquote:show/1?t:ac=4">News number 1</a></li> > <li><a href="/news.newsquote:show/2?t:ac=4">News number 2</a></li> > <li><a href="/news.newsquote:show/3?t:ac=4">News number 3</a></li> > <li><a href="/news.newsquote:show/4?t:ac=4">News number 4</a> You picked > 4</li> > </ul> > </body> > </html> > > Josh > > On Wed, Apr 30, 2008 at 2:49 PM, Chris Lewis <[EMAIL PROTECTED]> wrote: > >> I do hope we've missed a simpler way, but I don't think it's surfaced >> yet. Regarding parameters, how would that address the issue? NewsQuote >> displays a collection of items as links that represent selectable items >> (expressed as links). The action must be taken based on the user's >> selection, so a component parameter doesn't apply here. >> The event-based approach seems a theoretical perfect fit, but I can't >> see how to do it without using @Persist (which Janos wants to avoid). >> The only other thing I thought of is to have the NewsQuote component >> generate pagelinks based on the containing page instead of action links. >> This circumvents entirely the need for the events as the value will be >> in the page context, does not not make 2 requests, and ultimately gets >> the job done. It doesn't seem as elegant to me, but does the job and is >> completely decoupled from the page. >> >> Still not sure if we've had our epiphany yet :-) >> >> chris >> >> >> Josh Canfield wrote: >> >>>> I mean really, how is that any simpler than >>>> dealing directly with query parameters? >>>> >>>> >>> Hehe... I have to admit that I was solving a much more complicated >>> problem than the original question, probably brought on by an earlier >>> request about dynamic component rendering... I was shooting for >>> completely decoupled context handling for an unknown assortment of >>> components. Say you have 50 potential portlet components on a page >>> that may get included multiple times and may or may not add to the >>> context of the page, you probably don't want to manage that through >>> individual page properties. >>> >>> Anyway, >>> Isn't the straight forward solution to this problem to use component >>> parameters as Joel pointed out? If your NewsQuote component accepts a >>> newsId parameter, that binding is bi-directional. When the event >>> occurs in the component it calls the setter of the bound parameter, >>> which updates the value in the page and gets put back into the url via >>> context returned by onPassivate. When the value is set during render >>> time the component grabs the news item and renders it, if not it grabs >>> the top five and displays them... >>> >>> Perhaps as Joel pointed out we're just making this too complicated and >>> we should be the ones kicked out! >>> >>> Josh >>> >>> On Wed, Apr 30, 2008 at 1:27 PM, Chris Lewis <[EMAIL PROTECTED]> wrote: >>> >>> >>>> I see how this whole push on/pull off environment will solve the issue, >>>> but it just seems so nasty. I mean really, how is that any simpler than >>>> dealing directly with query parameters? I point at this only to >>>> highlight that perhaps Janos has brought to light a legitimately rough >>>> edge in T5, or else there's a cleaner way to do it and we're all just >>>> missing it. I'm convinced that the event system is the way to go as it >>>> seems a natural fit, but the redirect-after-action part is rendering it >>>> useless without using @Persist! Let me share what I've put together, and >>>> maybe someone will find the missing piece. I have a working test and >>>> I'll abbreviate the code here and assume a few things: >>>> >>>> (coming in another message - i tripped the spam filter :-| ) >>>> >>>> >>>> Josh Canfield wrote: >>>> >>>> >>>>> Are you trying to keep the news id out of the url? Doesn't sound like >>>>> it from your response to not doing the redirect. Since that's the >>>>> case, why not add it to the page context? >>>>> >>>>> I suppose if you were building a portal with several components then >>>>> keeping track of component parameters could get unwieldy. If you were >>>>> showing a news article from the news portlet, and a stock highlight >>>>> from the stock portlet... At that point you're sort of building a >>>>> framework on a framework. >>>>> >>>>> You could build your page such that it accumulated context from it's >>>>> components. Push a ComponentContext object into the Environment >>>>> onActivate, and setupRender in your page (env gets cleared before >>>>> render phase, not sure if there is a better way than doing it in >>>>> both.) Then collect component parameter mappings. onPassivate for your >>>>> page would organize and return these as it's context (you might want >>>>> to sort them to get consistent results) >>>>> >>>>> Your url might look like this: >>>>> >>>>> http://localhost/context/mypage/cc/news/4527/stock/MCD >>>>> >>>>> Then onactivate you init the ComponentContext from the url keying off >>>>> the "cc" to grab the remaining parameters and use them as key/value >>>>> for the components. The your components do something like: >>>>> >>>>> @Environmental >>>>> private ComponentContext _compContext; >>>>> >>>>> void setupRender() { >>>>> Long newsId = _compContext.getLong(_resources.getId()); >>>>> } >>>>> >>>>> void onPickNewsItem(Long id) { >>>>> _compContext.put(_resources.getId(), id); >>>>> } >>>>> >>>>> >>>>> Josh >>>>> >>>>> On Wed, Apr 30, 2008 at 5:23 AM, János Jarecsni >>>>> <[EMAIL PROTECTED]> wrote: >>>>> >>>>> >>>>> >>>>>> Hi Chris, >>>>>> >>>>>> I try to explain :) >>>>>> Say, you have a "NewsQuote" component, which shows a few lines from the 5 >>>>>> latest news. At the and of each quotations, there a "More" link. Now, >>>>>> when >>>>>> the user clicks on this link (an action link, for that matter), the >>>>>> NewsQuote component will set a request scope info saying that the news >>>>>> with >>>>>> ID=4527 is requested. And when it comes to the "News" component (it is >>>>>> able >>>>>> to show the text of a given news in full), it simply looks at this piece >>>>>> of >>>>>> info, and loads the news with id 4527 (or gets it from an app level cache >>>>>> :)) and renders it. >>>>>> >>>>>> Hope it tells something about what I am up to :) >>>>>> >>>>>> thx >>>>>> Janos >>>>>> >>>>>> 2008/4/30 Chris Lewis <[EMAIL PROTECTED]>: >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>>> Honestly it's difficult for me to imagine a situation where I'd do that >>>>>>> because it seems to violate a degree of encapsulation that tapestry >>>>>>> imposes as a "freeing law" of the framework. The epicenter of that being >>>>>>> that one should not think in terms of low-level idioms such as request >>>>>>> parameters, and instead replace those with a higher level of application >>>>>>> logic that eclipses them entirely (when possible). That's not to say >>>>>>> that your perspective is flawed, but from the small bit of understanding >>>>>>> I've taken from your posts I can't see why one would do what you want. >>>>>>> The thing that I've been saying is missing here is, what are you trying >>>>>>> to do? I don't mean technically, I mean what is the end result for the >>>>>>> user? Understanding this is critical, but even if I don't your problem >>>>>>> can still be solved by using a session to serve as an arbitrary holder. >>>>>>> If you've settled on this architecture, why not write such a generic >>>>>>> service and move on? >>>>>>> >>>>>>> >>>>>>> >>>>>>> >> -- >> http://thegodcode.net >> >> >> > > > > -- http://thegodcode.net