How pass params to Thymeleaf Ajax Fragment

2020-07-23 04:36发布

问题:

I have a Spring MVC controller that returns the name of a thymeleaf fragment to view resolver bean. The problem is that this fragment needs a url as a parameter. Here I put the fragment:

     <!-- A fragment with wrapper form for basic personal information fragment -->
 <th:block th:fragment="form-basic(url)">
    <form role="form" th:action="${url}" method="post" th:object="${user}">
         <th:block th:replace="admin/fragments/alerts::form-errors"></th:block>
         <th:block th:include="this::basic" th:remove="tag"/>
         <div class="margiv-top-10">
              <input type="submit"  class="btn green-haze" value="Save" th:value="#{admin.user.form.save}" />
              <input type="reset"  class="btn default" value="Reset" th:value="#{admin.user.form.reset}" />
        </div>
  </form>
</th:block>

I can not get a way to pass that parameter without getting an error. The controller is as follows:

@RequestMapping(method = RequestMethod.GET)
public String show(@CurrentUser User user, Model model) {
   logger.info(user.toString());
   if(!model.containsAttribute(BINDING_RESULT_NAME)) {
       model.addAttribute(ATTRIBUTE_NAME, user);
   }
   model.addAttribute("url", "/admin/users/self/profile");
   return "admin/fragments/user/personal::form-basic({url})";
}

For the above example I get the following error:

06-Jan-2017 11:36:40.264 GRAVE [http-nio-8080-exec-9] org.apache.catalina.core.StandardWrapperValve.invoke El Servlet.service() para el servlet [dispatcher] en el contexto con ruta [/ejercicio3] lanzó la excepción [Request processing failed; nested exception is java.lang.IllegalArgumentException: Invalid template name specification: 'admin/fragments/user/personal::form-basic({url})'] con causa raíz
 java.lang.IllegalArgumentException: Invalid template name specification: 'admin/fragments/user/personal::form-basic({url})'
    at org.thymeleaf.spring4.view.ThymeleafView.renderFragment(ThymeleafView.java:275)
    at org.thymeleaf.spring4.view.ThymeleafView.render(ThymeleafView.java:189)
    at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1257)
    at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1037)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:980)

I have done these tests:

 "admin/fragments/user/personal::form-basic('{url}')";
"admin/fragments/user/personal::form-basic(@{/admin/users/self/profile})";
"admin/fragments/user/personal::form-basic(/admin/users/self/profile)";
"admin/fragments/user/personal::form-basic('/admin/users/self/profile')";

In all I get error

回答1:

You have two ways for pass parameter from controller to Thymeleaf fragment. First is the usual Spring way - throw the model:

@RequestMapping(method = RequestMethod.GET)
public String show(@CurrentUser User user, Model model) {
   model.addAttribute("url", "/admin/users/self/profile");
   return "admin/fragments/user/personal::form-basic";
}

That's enough. In this case you don't need specify any fragment parameters (even if you have it).

Second way is specify parameters in fragment name:

@RequestMapping(method = RequestMethod.GET)
public String show(@CurrentUser User user, Model model) {
   String url = "/admin/users/self/profile";
   return String.format("admin/fragments/user/personal::form-basic(url='%s')",url);
}

Note, that name of parameter must be specified, and the string value must be placed in single quotes. In this case you don't need add url variable into model.



回答2:

All you need to do is include your url parameter as model attribute (as you did). There is no need to notifying your fragment name in any way. Just return fragment name as it would have no parameters.

// rest of method body omitted
model.addAttribute("url", "/admin/users/self/profile");
return "admin/fragments/user/personal::form-basic";

Btw. I see that your url lead to some other endpoint. In that case you should use it in @{...} manner in your th:action attribute of the form.

<form role="form" th:action="@{${url}}" method="post" th:object="${user}">