[ https://issues.apache.org/jira/browse/WICKET-2119?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12675708#action_12675708 ]
Igor Vaynberg commented on WICKET-2119: --------------------------------------- notice i reverted the code from WICKET-2118, see my comment > Suggested new implementation of ComponentPropertyModel > ------------------------------------------------------ > > Key: WICKET-2119 > URL: https://issues.apache.org/jira/browse/WICKET-2119 > Project: Wicket > Issue Type: Improvement > Components: wicket > Affects Versions: 1.3.5 > Reporter: Willis Blackburn > Attachments: NewComponentPropertyModel.java, > NewComponentPropertyModelTest.java > > > I would like to propose a replacement for ComponentPropertyModel. > The existing version addresses a specific situation: How to use > CompoundPropertyModel with a child component that requires two models? > However, I think that the existing implementation has some issues: > 1. It doesn't actually behave like the model-finding logic of Component. > Component searches up the component hierarchy until it finds a component with > a model that implements IComponentInheritedModel. ComponentPropertyModel > just uses the parent component's model. So if, for example, a Page with a > CompoundPropertyModel contains a model-less Form, and the Form contains > model-less fields, then the fields will find the Page model, but any > ComponentPropertyModels will try to access the Form model. > 2. ComponentPropertyModel can *only* use a property of the parent's model > and not the parent's model itself. > 3. It implements IComponentAssignedModel, which is confusing for Wicket > beginners. Sometimes IComponentAssignedModel is unavoidable, but in this > case, the component is only needed in order to access its parent, which is an > issue in itself (issue 1). In almost all cases, the parent of a Component > using ComponentPropertyModel is already known, so why not just pass it to > ComponentPropertyModel directly? > My proposed implementation accepts a Component and delegates operations to > that Component's model. It also optionally allows an expression for > accessing a specific property of the target Component's model. This > addresses a very common use case: A Component needing to use the model of > some other Component directly. As an example, AjaxEditableLabel creates two > components that both use AjaxEditableLabel's model. > Having a component that directly uses the model of some other component is > difficult with existing model implementations. The obvious way to do it is > to call getModel on the parent component, then use the returned model in the > child components, either directly or in combination with PropertyModel. > There are two gotchas with this approach: > First, the model of the parent component may not be known in the parent > constructor: The parent may not have a model and may expect to get its model > from an IComponentInheritedModel higher in the component hierarchy, however > the parent has not yet been added to *its* parent in the constructor, and so > the inherited model is not yet available. Therefore, a Component that wants > to create children that use its own model cannot create those children it in > its constructor. It must lazily create them in the onBeforeRender method > instead. > Second, and more generally, an application can call setModel on the component > at any time. If the component passes its model to its children, then it also > has to intercept setModel and reset the child models. AjaxEditableLabel does > this, but it only has two child components to manage. > A strategy for child components that want to use their parent's model is to > create a PropertyModel in which the target object is the Component containing > the actual model and the property expression starts with "modelObject." > Basically, my proposed ComponentPropertyModel implements this functionality, > except that the "modelObject" part of the expression is implied. For this > particular use case, it is clearer and a bit more efficient than new > PropertyModel(someComponent, "modelObject.property.expression"). > Using this model, AjaxEditableLabel would become much simpler. It could > create the child Label and TextField components once, in the constructor, > passing new ComponentPropertyModel(this), and not have to worry about > onBeforeRender or setModel. > Let me know what you think. > I wrote a test case for this, but I can't actually run it due to the issue > with the component instantiation listener that Application installs; see my > other jIRA issue about this. -- This message is automatically generated by JIRA. - You can reply to this email to add a comment to the issue online.