How to adapt child node in sling aem6 model

I am learning to use one of the new features of the AEM6 models - Sling. I already selected the node properties, following the steps described here below

@Model(adaptables = Resource.class) public class UserInfo { @Inject @Named("jcr:title") private String title; @Inject @Default(values = "xyz") private String firstName; @Inject @Default(values = "xyz") private String lastName; @Inject @Default(values = "xyz") private String city; @Inject @Default(values = "aem") private String technology; public String getFirstName() { return firstName; } public String getLastName() { return lastName; } public String getTechnology() { return technology; } public String getTitle() { return title; } } 

and adapted it from the resource

 UserInfo userInfo = resource.adaptTo(UserInfo.class); 

Now I have a hierarchy like -

 + UserInfo (firstName, lastName, technology) | + UserAddress (houseNo, locality, city, state) 

Now I want to get UserAddress properties.

I had some hints on the documentation page, such as

If the entered object does not match the desired type, and the object implements the Adaptable interface, Sling Models will try to adapt it. This provides the ability to create graphs of objects. For instance:

 @Model(adaptables = Resource.class) public interface MyModel { @Inject ImageModel getImage(); } @Model(adaptables = Resource.class) public interface ImageModel { @Inject String getPath(); } 

When a resource is adapted to MyModel , a child resource named image automatically adapts to the ImageModel instance.

but I don’t know how to implement it in my classes. Please help me with this.

+5
source share
1 answer

It seems you need a separate class for UserAddress to wrap houseNo , city , state and locality properties.

 + UserInfo (firstName, lastName, technology) | + UserAddress (houseNo, locality, city, state) 

Just reflect the structure specified in your Sling models.

Create a UserAddress Model:

 @Model(adaptables = Resource.class) public class UserAddress { @Inject private String houseNo; @Inject private String locality; @Inject private String city; @Inject private String state; //getters } 

This model can then be used in your UserInfo class:

 @Model(adaptables = Resource.class) public class UserInfo { /* * This assumes the hierarchy you described is * mirrored in the content structure. * The resource you're adapting to UserInfo * is expected to have a child resource named * userAddress. The @Named annotation should * also work here if you need it for some reason. */ @Inject @Optional private UserAddress userAddress; public UserAddress getUserAddress() { return this.userAddress; } //simple properties (Strings and built-in types) omitted for brevity } 

You can customize the behavior with additional annotations for the default values ​​and optional fields, but this is a general idea.

In general, Sling models should be able to handle the injection of another model if it finds a suitable adaptable one. This is another Sling model in this case, but I did it with inherited classes based on adapter factories.

+4
source

All Articles