You're right, getDefaultModel ensures initialization. I should have suggested
that instead of getModel (which is not available in the component class anymore
in 1.4.x).

However, I did not want to override the initModel() method (and copy most of its
code) just for that. So now I solved it by creating a new wrap model, which I
pass to the child component and which wraps around the parent.getDefaultModel().

public class ComponentWrapModel<T> implements IWrapModel<T> {
        private Component component;
        public ComponentWrapModel(Component component) { // component = parent
                this.component=component;
        }
        
        @Override
        public IModel<?> getWrappedModel() {
                return component.getDefaultModel();
        }
....
}

Here's some more background which should explain why I chose to do this:
I replace form components (eg. Textfield) with custom components (eg.
MyTextfield) to add a few things my application needs to them. The name
MyTextfield is a bit misleading here, because this is actually a subclass of
Panel, and it merely contains a Textfield as a child. Still I wanted to use
MyTextfield as a drop-in replacement, even when used in a form with a
CompoundPropertyModel. This is where things got a little tricky, because the
Textfield would end up trying to retrieve a property model matching its own
wicket:id, when the relevant wicket:id had now become that of MyTextfield.

Anyway I would have expected that wicket ensures the parent component model gets
initialized first, seeing how components generally query their parents when they
don't have a model of their own. And I'm still considering to report this as a
bug in Jira.

Cheers
 Edmund


Pedro Santos wrote:
> The child model's initModel() gets called first
> There are no especial ordering programing to initModels calls. Basically
> they are called by
> 
>     public final IModel<?> getDefaultModel()
>     {
>         IModel<?> model = getModelImpl();
>         // If model is null
>         if (model == null)
>         {
>             // give subclass a chance to lazy-init model
>             model = initModel();
>             setModelImpl(model);
>         }
> 
>         return model;
>     }
> What about your custom component gain an model that implements
> IComponentInheritedModel and assign his children default models with the
> desired logic? On IComponentInheritedModel you can access your custom
> component parent model, and if you use getDefaultModel method, you don't
> need to care with initialization ordering too...
> 
> On Wed, Sep 30, 2009 at 9:51 AM, Edmund Urbani <e...@liland.org> wrote:
> 
>> Hi,
>>
>> I was just trying to create a component of my own which - in some of my
>> pages -
>> is created without a model. In the initModel() method I would then call
>> super.initModel() and wrap the resulting model for use in a child
>> component. The
>> problem is the initialization order:
>>
>> The child model's initModel() gets called first, the parent (my custom
>> component) does not yet have a model (getModelImpl() returns null) so it
>> goes up
>> farther in the component hierarchy and retrieves a wrong model.
>>
>> Looking at the Component source code (Wicket 1.4.1) I see a commented out
>> line
>> where initModel() used to to call the parent getModel() instead of
>> getModelImpl(). There's also a comment explaining that doing so would
>> "initialize many inbetween completely useless models". Well, not so useless
>> for
>> what I am trying to do I guess.
>>
>> So, from my perspective this looks like a bug that causes necessary
>> initialization to be bypassed. Obviously though it was done like that on
>> purpose, so I decided to put the issue up here instead of filing a bug
>> report.
>>
>> Has anyone else run into similar issues?
>> Would it really be so bad to just call getModel()?
>>
>> Cheers
>>  Edmund
>>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
For additional commands, e-mail: users-h...@wicket.apache.org

Reply via email to