0
votes

2 Sling Models are given and I want to inject one of them. Is this possible with an annotation or do I need to create a PostContruct method as a workaround?

Example:

Model A

@Model(adaptables = Resource.class)
public class ModelA { 
   @ValueMapValue(name = "jcr:title", injectionStrategy = InjectionStrategy.OPTIONAL)
   private String title;

   @Inject // Not working! 
   private ModelB modelB;
}

Model B

@Model(adaptables = Resource.class)
public class ModelB { 
   @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL)
   private String text;

}
2
Is the resource that is represented by ModelB a child resource of the resource represented by ModelA? - Jens
No, it is the same resource. - nicolas
So you have a ResourceA and you want to adapt that resource to ModelA and ModelB at the same time? What you want to do is possible, as long as the resource represented by ModelB is a child resource of the resource represented by ModelA. See sling.apache.org/documentation/bundles/models.html#adaptations - Jens

2 Answers

4
votes

Since 1.1.0 version of Sling Models you can use @Self annotation to inject models which can be adapted from current adaptable. In this case from Resource of ModelA.

Injects the adaptable object itself (if the class of the field matches or is a supertype). If the @Self annotation is present it is tried to adapt the adaptable to the field type.

@Model(adaptables = Resource.class)
public class ModelA { 
   @ValueMapValue(name = "jcr:title", injectionStrategy = InjectionStrategy.OPTIONAL)
   private String title;

   @Inject // This should works
   @Self
   private ModelB modelB;
}
0
votes

You wont be able to inject ModelB into ModelA, what you can do is get the resource instance in ModelA and adapt it to ModelB

@Model(adaptables = SlingHttpServletRequest.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class ModelA { 
   @Inject
   @Via("resource") 
   @Named("jcr:title")
   private String title;

   @Inject 
   private Resource resource;

  @PostConstruct
  public void init() {
   final ModelB modelb = resource.adaptTo(ModelB.class);
   }
}