A basic looping component; loops over a number of items (provided by its source parameter), rendering its body for each one。tapestry5 When a Loop is inside a Form, it records quite a bit of state into the Form to coordinate access to the same (or equivalent) objects during the form submission as during the render。 This is controlled by the formState parameter (of type LoopFormState) and can be 'none' (nothing stored into the form), 'values' (which stores the individual values looped over, or via a ValueEncoder, just the value's ids), and 'iteration' (which just stores indexes to the values within the source parameter, which means that the source parameter will be accessed during the form submission)。
For a non-volatile Loop inside the form, the Loop stores a series of commands that start and end heartbeats, and stores state for each value in the source parameter (either as full objects when the encoder parameter is not bound, or as client-side objects when there is an encoder)。 For a Loop that doesn't need to be aware of the enclosing Form (if any), the formState parameter should be bound to 'none'。 When the Loop is used inside a Form, it will generate an event to inform its container what values were submitted and in what order; this can allow the container to pre-load the values in a single batch form external storage, if that is appropriate。tapestry5
Component ParametersNameTypeFlagsDefaultDefault Prefix
The element to render. If not null, then the loop will render the indicated element around its body (on each pass through the loop). The default is derived from the component template.
A ValueEncoder used to convert server-side objects (provided by the "value" parameter) into unique client-side strings (typically IDs) and back. In general, when using a non-volatile Loop in a Form, you should either provide a ValueEncoder with the encoder parameter or use a "value" type for which Tapestry is configured to provide a ValueEncoder automatically. Otherwise Tapestry must fall back to using the plain index of each loop iteration, rather than the ValueEncoder-provided unique ID, for recording state into the form.
org.apache.tapestry5.corelib.LoopFormState
Controls what information, if any, is encoded into an enclosing Form. The default value is org.apache.tapestry5.corelib.LoopFormState#VALUES. This parameter is only used if the component is enclosed by a Form.
Component EventsNameDescription

This example is based around a NavBar component that generates a setof links to other pages in the applilcation.
<table class="navigation" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
<tr>
<t:loop source="pageNames" value="pageName">
<td class="${tabClass}">
<t:pagelink page="pageName">${pageName}</t:pagelink>
</td>
</t:loop>
</tr>
</table>
We are assuming that the NavBar componenthas a pageNames property (possibly a parameter). The Loop williterate over those page names and store each into its value parameter.
public class NavBar
{
@Parameter(defaultPrefix="literal", required=true)
private String pages;
@Inject
private ComponentResources resources;
@Property
private String _pageName;
public String[] getPageNames()
{
return pages.split(",");
}
public String getTabClass()
{
if (pageName.equalsIgnoreCase(resources.getPageName())
return "current";
return null;
}
}
The component converts its pages parameter into the pageNames propertyby splitting it at the commas. It tracks the current pageName of the loopnot just to generate the links, but to calculate the CSS class of each element on the fly. This way we can give the tab correspondingto the current page a special look or highlight.
We can fold together the Loop component and the element:
<table class="navigation" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
<tr>
<td t:type="loop" source="pageNames" value="pageName" class="${tabClass}">
<t:pagelink page="pageName">${pageName}</t:pagelink>
</td>
</tr>
</table>
Using thet:type="loop"attribute, the other way to identify a templateelement as a component, allows the Loop component to render the element's tag,the on each iteration, along with informal parameters (the class attribute). This iscalledinvisible instrumentation, and it is more concise and moreeditor/preview friendly than Tapestry's typical markup.

Tapestry form control element components (TextField, etc.) work inside loops. However,some additional configuration is needed to make this work efficiently.
With no extra configuration, each value object will be serialized into the form (ifyou view the rendered markup, you'll see a hidden form field containing serialized data needed byTapestry to process the form). This can become very bloated, or may not work if the objects beingiteratedare not serializable.
The typical case is database driven; you are editting objects from a database and needthose objects back when the form is submitted. All that should be storedon the client is theidsof those objects. Thats what the encoderparameter is for.
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
<body>
<h1>Edit Order Quantities</h1>
<t:form>
<t:errors/>
<t:loop source="items" value="item" encoder="encoder">
<div class="line-item">
<t:label for="quantity">${item.product.name}</t:label>
<t:textfield t:id="quantity" value="item.quantity"/>
</div>
</t:loop>
<input type="submit" value="Update"/>
</t:form>
</body>
</html>
The TextField component is rendered multiple times, oncefor each LineItem in the Order.
public class EditOrder
{
@Inject
private OrderDAO orderDAO;
@Property
private final ValueEncoder<LineItem> encoder = new ValueEncoder<LineItem>()
{
public String toClient(LineItem value) { return String.valueOf(value.getId()); }
public LineItem toValue(String clientValue)
{
long id = Long.parseLong(clientValue);
return orderDAO.getLineItem(id);
}
};
@Persist
private long orderId;
@Property
private LineItem item;
public List<LineItem> getItems()
{
return orderDAO.getLineItemsForOrder(orderId);
}
}
Here, we expect the OrderDAO service to do most of the work,and we create a wrapper around it, in the form of theValueEncoder instance.
We've glossed over a few issues here, including how to handlethe case that a particular item has been deleted or changedbetween the render request and the form submission, as well as how the orderIdproperty gets set in the first place.
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-31296-1.html
毕竟是中国先到美国十二海里