【问题标题】:Problem populating a modal dynamically with ThymeLeaf and Spring MVC使用 ThymeLeaf 和 Spring MVC 动态填充模式的问题
【发布时间】:2018-11-07 18:10:00
【问题描述】:

这是我的主页页面。

当用户选择数据中心时,页面会重定向并显示该数据中心可用的 FisicHost 列表。

数据中心类

@Entity
@Transactional
public class Datacenter {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    private String name;

    @OneToMany(mappedBy = "datacenter")
    @LazyCollection(LazyCollectionOption.FALSE)
    private List<FisicHost> fisicHostList;

  // I've cut the constructor and get/set to make it shorter
}

这是用户在选择数据中心时被重定向的视图:

视图中的每一行代表一个可用于所选数据中心的 FiscHost 对象。

FisicHost 类

@Entity
@Transactional
public class FisicHost {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToOne(fetch=FetchType.EAGER)
private Datacenter datacenter;

@OneToMany(mappedBy = "fisicHost")
@LazyCollection(LazyCollectionOption.FALSE)
private List<Credential> credentials;

private String name;
private String ip;
private String operatingSystem;
private String notes;
}

这是处理第二个视图的控制器方法(显示该数据中心可用 FisicHost 列表的视图):

@RequestMapping(value = "/chosenDatacenter", method = RequestMethod.POST)
public String datacenterPostHandler(@RequestParam("datacenterList") String name, ModelMap modelMap){
    List<Datacenter> allDatacenters = datacenterDao.getAllDatacenters();
    for (Datacenter dc : allDatacenters) {
        if (dc.getName().equals(name)) {
        modelMap.put("datacenter", dc);
        if(dc.getFisicHostList().size() != 0) {
            List<FisicHost> datacenterFisicHosts = dc.getFisicHostList();
            modelMap.put("datacenterFisicHosts", datacenterFisicHosts);
            for(FisicHost fh : datacenterFisicHosts){
                if(fh.getCredentials().size() != 0){
                    modelMap.put("fisicHostCredentialsList", credentialDao.getAllCredentialsByFisicHost(fh));
                }
            }
        }
        return "chosenDatacenter";
        }
    }
        return null;
}

如果用户单击“CREDENCIALES”按钮,则会弹出一个模式并显示该 FisicHost 可用的所有凭据。

凭证类:

@Entity
public class Credential {

    @Id
    private int id;

    @ManyToOne(fetch= FetchType.EAGER)
    private FisicHost fisicHost;

    private String user;
    private String password;
    private String notes;
    private String role;
}

一切正常,但是问题来了...

无论单击什么按钮,都会打开模式,显示该数据中心内所有 FisicHost 的所有凭据,我只想显示在相应数据中心中单击的特定 FisicHost 的凭据!

我知道控制器中的这个逻辑:

 for(FisicHost fh : datacenterFisicHosts){
                if(fh.getCredentials().size() != 0){
                    modelMap.put("fisicHostCredentialsList", credentialDao.getAllCredentialsByFisicHost(fh));
                }

只是带回循环的最后一次迭代,因此无论如何它都会带回该 FisicHost 的凭据!这就是正在发生的事情,但我找不到其他方法......

以防万一,这里是 CredentialDaoImpl 类中的 getAllCredentialsByFisicHost() 方法:

@Override
public List<Credential> getAllCredentialsByFisicHost(FisicHost fisicHost) {
    // Open a session
    Session session = sessionFactory.openSession();

    Criteria c = session.createCriteria(Credential.class).add(Restrictions.eq("fisicHost.id", fisicHost.getId()));

    List<Credential> allCredentials = c.list();

    // Close the session
    session.close();

    return allCredentials;
}

请帮忙,因为我要疯了!!!

非常感谢大家:)

PS:这是使用 ThymeLeaf 渲染的 chosenDatacenter 模板:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8" />
    <title>Generic View</title>
    <link rel="stylesheet" th:href="@{/css/bootstrap/bootstrap.min.css}" />
    <link rel="stylesheet" th:href="@{/css/choosenDatacenter.css}" />
</head>

<body>

<form id="form" action="/getJson" th:object="${datacenterFisicHosts}" method="post">

    <table>
        <tr class="row">
            <th class="tableHeader">Nombre</th>
            <th class="tableHeader">IP</th>
            <th class="tableHeaders">Sistema Operativo</th>
            <th class="tableHeaders">Notas</th>
        </tr>

        <th:block th:each="fh : ${datacenterFisicHosts}">
        <div id="fila">
            <tr class="row">
                <td id="fisicHostName" th:text="${fh.name}"></td>
                <td id="fisicHostIp" th:text="${fh.ip}"></td>
                <td id="fisicHostOS" th:text="${fh.operatingSystem}"></td>
                <td id="fisicHostNotes" th:text="${fh.notes}"></td>
                <td><button type="button" th:onclick="'javascript:openCredentialModal()'">CREDENCIALES</button></td>
            </tr>
        </div>
        </th:block>
    </table>

</form>


<!-- Modal -->
<div class="modal fade" id="modalCredenciales" tabindex="-1" role="dialog" aria-hidden="true">
    <div class="modal-dialog modal-dialog-centered" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="modal-title">Credenciales</h5>
            </div>
            <div class="modal-body">
                <table>
                    <tr class="row">
                        <th class="tableHeader">Usuario</th>
                        <th class="tableHeader">Clave</th>
                        <th class="tableHeaders">Notas</th>
                    </tr>

                    <th:block th:each="credential : ${fisicHostCredentialsList}">
                        <tr class="row">
                            <td id="credentialUser" th:text="${credential.user}"></td>
                            <td id="credentialPassword" th:text="${credential.password}"></td>
                            <td id="credentialRole" th:text="${credential.notes}"></td>
                        </tr>
                    </th:block>
                </table>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-dismiss="modal">Cerrar</button>
            </div>
        </div>
    </div>
</div>

<script th:src="@{js/jquery-1.11.3.js}"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<script th:src="@{js/chosenDatacenter.js}"></script>
</body>
</html>

【问题讨论】:

    标签: java spring spring-mvc thymeleaf


    【解决方案1】:

    您可以使用 Ajax 将 id 传递给您的控制器并让它只返回相关的证书,如 here 所述。

    在您的控制器中添加一个方法,该方法以 fisicHost 的 id 作为参数返回正确的凭据列表:

    @RequestMapping("/fisicHost/{id}")
    public String fisicHost credentials(@PathVariable("id") String id, ModelMap model) 
    {
        //find credentials by fisicHost using your DAO and add them to model
        return "modal/credentials :: modalContents";
    }
    

    您需要一个“modalContents”Thymeleaf 片段来显示添加到模型中的凭据。

    然后在onClick事件上,可以使用Ajax调用正确id的url并显示数据。在您的模板中,您将拥有:

    th:onclick="'javascript:openCredentialModal(\'' + ${fh.id} + '\');'"
    

    Ajax 函数只是通过传递 id 来调用控制器的 url,并从 thymeleaf 片段中返回 html 代码。然后它将 html 内容打包到 modal 中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-22
      • 1970-01-01
      • 2012-06-15
      • 2023-04-05
      • 2013-12-16
      • 2014-11-23
      • 2016-04-22
      • 1970-01-01
      相关资源
      最近更新 更多