AEM 6.3 - Multifield using Sling Model

三世轮回 提交于 2019-12-11 06:09:57

问题


I am trying to create a Coral UI 3 multifield and use Sling Models. Here is how the dialog looks like:

Here is the code :

    package com.aem.sites.models;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Named;

import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.Model;

import org.apache.log4j.Logger;

import com.aem.sites.models.Header;

@Model(adaptables=Resource.class)
public class HeaderList {

    final static Logger logger = Logger.getLogger(HeaderList.class);

    @Inject
    @Named("header")
    public Resource headerList;

    public List<Header> links;

    @PostConstruct
    protected void init() {
        links = new ArrayList<Header>();
        if(headerList != null) {
            logger.info("value of header list is "+headerList);
            links = populateModel(links, headerList);
        }
    }

    public  List<Header> populateModel(List<Header> array, Resource resource) {
        if(resource != null) {
            Iterator<Resource> linkResource = resource.listChildren();
            while(linkResource.hasNext()) {
                Header header = linkResource.next().adaptTo(Header.class);
                if(header != null) {
                    array.add(header);
                }
            }
        }
        return array;
    }

    public List<Header> getLinks() {
        return links;
    }

}


    package com.aem.sites.models;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Named;

import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.Model;

//Creating adaptable resource class using sling annotation 
@Model(adaptables = Resource.class)
public class Header {

    @Inject
    @Named("linkText")
    private String linkText;

    @Inject
    @Named("linkUrl")
    private String linkUrl;

    @PostConstruct
    protected void init() {

    }

    public String getTitle() {
        return linkText;
    }

    public String getUrl() {
        return linkUrl;
    }

    public void setTitle(String title) {
        linkText = title;
    }

    public void setUrl(String url) {
        linkUrl = url;
    }
}

and here is the HTL file:

<header id="header" class="skel-layers-fixed">
 <nav id="nav">
 <h1><a href="#">Ion</a></h1>
<sly data-sly-use.headerObj="com.aem.sites.models.HeaderList">
<ul data-sly-list="${headerObj.items.listChildren}">
<li><a href="${item.linkUrl @context='styleToken'}">${item.linkText @context='styleToken'}</a></li>
</ul>
</sly>
</nav>
</header>

and here is the error I have been getting :

Caused by: org.apache.sling.models.factory.MissingElementsException: Could not inject all required fields into class com.aem.sites.models.HeaderList
    at org.apache.sling.models.impl.ModelAdapterFactory.createObject(ModelAdapterFactory.java:593)
    at org.apache.sling.models.impl.ModelAdapterFactory.internalCreateModel(ModelAdapterFactory.java:335)
    at org.apache.sling.models.impl.ModelAdapterFactory.createModel(ModelAdapterFactory.java:223)
    at org.apache.sling.scripting.sightly.models.impl.SlingModelsUseProvider.provide(SlingModelsUseProvider.java:135)
    at org.apache.sling.scripting.sightly.impl.engine.extension.use.UseRuntimeExtension.call(UseRuntimeExtension.java:72)
    ... 209 common frames omitted
    Suppressed: org.apache.sling.models.factory.MissingElementException: Could not inject public org.apache.sling.api.resource.Resource com.aem.sites.models.HeaderList.headerList
        at org.apache.sling.models.impl.ModelAdapterFactory.createObject(ModelAdapterFactory.java:598)
        ... 213 common frames omitted
    Caused by: org.apache.sling.models.factory.ModelClassException: No injector returned a non-null value!
        at org.apache.sling.models.impl.ModelAdapterFactory.injectElement(ModelAdapterFactory.java:513)
        at org.apache.sling.models.impl.ModelAdapterFactory.createObject(ModelAdapterFactory.java:596)

I am not sure what I am doing wrong here. I am not sure if it has something to do with the dialog ? That's what I suspect.

Any help is appreciated.

Thanks in advance.


回答1:


The error is thrown because the attribute headerList in your model cannot be injected successfully. You need to be able to fetch the items node so that you can then list it's children. Perhaps try the following:

@Model(adaptables=Resource.class)
public class HeaderList {

    final static Logger logger = Logger.getLogger(HeaderList.class);

    @Inject
    @Named("items") <--------- changed this
    public Resource headerList;

    public List<Header> links;

    @PostConstruct
    protected void init() {
        links = new ArrayList<Header>();
        if(headerList != null) {
            logger.info("value of header list is "+headerList);
            links = populateModel(links, headerList);
        }
    }

    public  List<Header> populateModel(List<Header> array, Resource resource) {
        if(resource != null) {
            Iterator<Resource> linkResource = resource.listChildren();
            while(linkResource.hasNext()) {
                Header header = linkResource.next().adaptTo(Header.class);
                if(header != null) {
                    array.add(header);
                }
            }
        }
        return array;
    }

    public List<Header> getLinks() {
        return links;
    }
}

and in your template, just use the links property:

<sly data-sly-use.headerObj="com.aem.sites.models.HeaderList">
  <ul data-sly-list="${headerObj.links}">
    <li><a href="${item.linkUrl @context='styleToken'}">${item.linkText @context='styleToken'}</a>
    </li>
  </ul>
</sly>


来源:https://stackoverflow.com/questions/46516703/aem-6-3-multifield-using-sling-model

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!