简体   繁体   English

Thymeleaf webflux:只允许将一个数据驱动变量指定为模型属性,但至少已识别出两个

[英]Thymeleaf webflux: Only one data-driver variable is allowed to be specified as a model attribute, but at least two have been identified

I'm trying to create a dashboard application where multiple widgets get updates through SSE.我正在尝试创建一个仪表板应用程序,其中多个小部件通过 SSE 获取更新。 My DashboardController looks like:我的仪表板控制器看起来像:

public class DashboardController
{
    private WidgetService widgetService;

    public DashboardController(WidgetService widgetService)
    {
        this.widgetService = widgetService;
    }

    @GetMapping("/")
    public String index(final Model model)
    {
        for(WidgetInterface<?> widget : widgetService.getAll()) {
            model.addAttribute("widget-data-driver-" + widget.getIdentifier(),
                    new ReactiveDataDriverContextVariable(widget.getInitialData(), 100));
        }
        model.addAttribute("widgets", widgetService.getAll());
        return "index";
    }
}

And my WidgetInterface:还有我的小部件接口:

public interface WidgetInterface<T>
{
    public String getIdentifier();
    public String getTitle();
    public String getStreamEndpoint();
    public Flux<T> getInitialData();
    public Map<String, String> getColumns();
    public String getThymeLeafFraction();
    public Date getLastItemDate();
    public Flux<T> getItemsUpdatedSince(Date date);
}

All is working fine for one widget (from the WidgetService).一个小部件(来自 WidgetService)一切正常。 I'm trying to pass a ReactiveDataDriverContextVariable for each widget to Thymeleaf.我正在尝试将每个小部件的ReactiveDataDriverContextVariable传递给 Thymeleaf。 But I get the following error:但我收到以下错误:

org.thymeleaf.exceptions.TemplateProcessingException: Only one data-driver variable is allowed to be specified as a model attribute, but at least two have been identified: 'widget-data-driver-nufeed' and 'widget-data-driver-weatherapi'

I have two active widgets, one is an RSS feed an one implements weather api.我有两个活动小部件,一个是 RSS 提要,一个是实现天气 api。 I understand the error, but how to can I set up the reactive variables for multiple widgets?我理解错误,但是如何为多个小部件设置反应变量?

Update my thymeleaf template更新我的百里香模板

<!DOCTYPE html>  
<html xmlns:th="http://www.w3.org/1999/xhtml" th:with="version=7">  
<head>  
 <meta charset="utf-8">  
 <meta http-equiv="X-UA-Compatible" content="IE=edge">  
 <meta name="viewport" content="width=device-width, initial-scale=1">  
 <link rel="icon" type="image/png" href="images/logo.png" />  
 <title>Dashboard</title>  
 <link rel="stylesheet" th:href="'build/vendor.css?v=' + ${version}" />  
 <link rel="stylesheet" th:href="'build/app.css?v=' + ${version}" />  
 <link rel="preconnect" href="https://fonts.googleapis.com">  
 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>  
 <link href="https://fonts.googleapis.com/css2?family=Space+Mono&display=swap" rel="stylesheet">  
</head>  
<body>  
 <div class="container-fluid" id="content">  
 <div class="container" id="content-body">  
 <div class="logo-header">  
 <img src="images/logo.png" align="left">  
 <h2>Dashboard <a href="/logout" class="logout"><span>(logout)</span></a></h2>  
 </div>  
 <div class="row" id="widgets">  
 <div class="col-xl-4 col-lg-6 col-md-6 col-sm-12 col-12 card-container" th:each="widget: ${widgets}" th:data-identifier="@{${widget.identifier}}">  
 <div class="card p-3 mb-2" th:classappend="@{${widget.getCardCssClass()}}">  
 <div class="card-header" th:if="${widget.title != null}">  
 <div class="widget-icon-header"><img class="widget-icon" th:src="${widget.icon}" /></div>  
 <div class="float-left" th:text="${widget.title}"></div>  
 <div class="float-right reload" th:if="${widget.hasUpdate}" th:data-ref="''+@{${widget.identifier}}+''"><img class="reload-img" src="images/reload.png"></div>  
 </div> <div class="card-body" th:id="''+@{${widget.identifier}}+'-content'">  
 <table th:replace="__${widget.getThymeLeafFraction()}__"></table>  
 </div> </div> </div> </div> </div> <div class="row fullscreen">  
 <a href="javascript:openFullscreen()" style="margin: 0px auto; color:#000">Fullscreen</a>  
 </div> </div>  
 <script th:src="'build/vendor.js?v=' + ${version}"></script>  
 <script th:src="'build/app.js?v=' + ${version}"></script>  
</body>  
</html>

It includes a thymeleaf fraction depending on the widget:它包括一个百里香叶部分,具体取决于小部件:

<table th:id="@{${widget.identifier}}" class="table" th:classappend="@{${widget.getCardCssClass()}}">  
 <thead> <tr> <th data-th-each="column : ${widget.getColumns()}"  
  th:style="'width:'+@{${widget.getColumnWidth().get(column.key)}}+';'"  
  th:text="${column.value}"></th>  
 </tr> </thead> <tbody> <tr class="result" data-th-each="item : ${#vars.getVariable('widget-data-driver-__${widget.identifier}__')}" th:data-id="@{${item.id}}">  
 <td th:text="''+${item.driver}"></td>  
 <td th:text="''+${item.points}"></td>  
 </tr> </tbody></table>

Update answer based on Angelos comment根据 Angelos 评论更新答案

I tried to replace the DashboardController.index method with:我尝试将 DashboardController.index 方法替换为:

GetMapping("/")
public String index(final Model model, Authentication authentication)
{
     setAuthentication(authentication);
     Flux<WidgetInterface<?>> flux = Flux.just(widgetService.getAll().toArray(new WidgetInterface<?>[0]));
     model.addAttribute("widgets", new ReactiveDataDriverContextVariable(flux));
     return "index";
}

This is working, except for the fact that now I cannot iterate over my widget.getInitialData() in thymeleaf (this is a fraction file as described above):这是有效的,除了现在我无法在 thymeleaf 中迭代我的 widget.getInitialData() (这是如上所述的分数文件):

<div data-th-each="item : ${widget.getInitialData()}"  th:data-id="@{${item.id}}" id="art">
    <a th:data-lightbox="'' + ${widget.identifier}" th:href="${item.image}">
        <img th:src="'https://images.weserv.nl/?url=' + ${item.image} + '&w=200&h=200&fit=cover&a=top'" th:data-lightbox="'' + ${widget.identifier}"
             class="rounded d-block user-select-none" style="max-height:100px;max-width:150px;margin-right:10px;" align="left" />
    </a>
    <h5 th:text="${item.description}" class="card-title"></h5>
</div>

This gives this error:这给出了这个错误:

org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "item.id" (template: "art_fraction" - line 1, col 56)
    at org.thymeleaf.spring5.expression.SPELVariableExpressionEvaluator.evaluate(SPELVariableExpressionEvaluator.java:292) ~[thymeleaf-spring5-3.0.15.RELEASE.jar:3.0.15.RELEASE]

I'd make your template code little bit simpler.我会让你的模板代码更简单一些。 I'd change it in this way:我会这样改变它:

JAVA SIDE JAVA侧

GetMapping("/")
public String index(final Model model, Authentication authentication)
{
     setAuthentication(authentication);
     Flux<WidgetInterface<?>> flux = Flux.just(widgetService.getAll().toArray(new WidgetInterface<?>[0]));
     model.addAttribute("widgets", new ReactiveDataDriverContextVariable(flux));
     return "index";
}

TEMPLATE SIDE :模板侧

        <table class="table table-striped">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>Image</th>
                    <th>Identifier</th>
                </tr>
            </thead>
            <tbody>
                <tr data-th-each="myWidget : ${widgets}">
                    <td>[[${myWidget.id}]]</td>
                    <td>[[${myWidget.image}]]</td>
                    <td>[[${myWidget.identifier}]]</td>
                </tr>
            </tbody>
        </table>

Obviously this is a sample... adapt it to your case显然这是一个示例......根据您的情况调整它

Angelo安杰洛

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Webflux post 请求:只允许一个连接接收订阅者 - Webflux post request: Only one connection receive subscriber allowed 当我有两个recyclerview数据源,但是只有一个数据源被更改时,如何在recyclerview中使用notifyDataSetChanged() - How to use notifyDataSetChanged() in recyclerview, when I have two data sources for the recyclerview, but only one data source has been changed Thymeleaf 说模型属性为空 - Thymeleaf says Model attribute is null Java数据结构,用于查找和使用属性至少为X的对象 - Java data structure for finding and using objects that have attribute at least X JDO 没有字段被识别为主键字段 - JDO no fields have been identified as primary key fields 使用Thymeleaf和Spring MVC以一种形式添加属于两个具有不同属性名称的两个不同模型的对象 - Adding two objects that belong to two different models with similar attribute names in one form using Thymeleaf and Spring MVC 您确定的收件人不是指定信封的有效收件人 - The recipient you have identified is not a valid recipient of the specified envelope 如何只有一个可以用作Webdriver或Appiumdriver的驱动程序 - How to only have one driver that can be used as Webdriver or Appiumdriver 对于仅在一个类变量中有所不同的两个类,什么是合适的模式? - What is suitable pattern for two classes which have difference in one class variable only? 仅当有多个构造函数可用时,“变量可能尚未初始化” - “Variable might not have been initialized” only when multiple constructors are available
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM