【问题标题】:Ajax partial refreshing in post method with spring and thymeleaf使用 spring 和 thymeleaf 的 post 方法中的 Ajax 部分刷新
【发布时间】:2017-02-26 10:42:18
【问题描述】:

我在部分更新我的页面时遇到问题。 我用几句话解释了业务问题。我有用户个人资料,他可以在其中更改有关自己的任何信息 等:技能、个人信息、主要照片库。 一切正常,但我有一件烦人的事情,我的整个页面在添加等照片后刷新。

首先我显示主照片添加准确

<div th:fragment="photoDiv">
    <img id="mainPhoto" th:src="@{/profile/main/img}" alt=""/>
    <div>
        <form id="mainPhotoForm" action="#" th:action="@{/profile/main/upload}"
              enctype="multipart/form-data" method="post">
            <label for="files"><img src="../../img/plus.png"/> Upload photo</label>
            <input id="files" style="display:none;" type="file" accept="image/*" th:name="img"
                   onchange="document.getElementById('mainPhotoForm').submit();"/>
        </form>
    </div>
</div>

我的控制器

@PostMapping("/profile/main/img")
public String uploadingMianPhoto(@RequestParam("img") MultipartFile file,
                                 @ModelAttribute("userDto") userDto user) {
    String path = filesStrorage.storeFiles(file, getCurrentUserID());
    if (!path.isEmpty()) {
        Photo mainPhoto = new Photo();
        mainPhoto.setFileName(file.getOriginalFilename());
        mainPhoto.setPath(path);
        user.setProfilePhoto(mainPhoto);
    }
    return "/profile/edit";
}

// Load main photo
@RequestMapping(value = "/profile/main/upload")
public @ResponseBody
byte[] mainPhotoResponse(@ModelAttribute("userDto") UserDto user) throws IOException {
    Path path = Paths.get(user.getProfilePhoto().getPath());
    return Files.readAllBytes(path);
}

我只想更新th:fragment="photoDiv" 而不是整个页面。

我尝试了 ajax 片段更新,但我没有使用 spring webflow,我应该添加 spring webflow 配置还是可以通过 jquery 来做到这一点?

所以在尝试之后

我添加了uploadingMianPhoto return "/profile/edit :: photoDiv",但它只返回我整个页面上的这个片段

请给我一些ajax post函数的例子,请给我一些解释

【问题讨论】:

    标签: javascript jquery ajax spring-mvc thymeleaf


    【解决方案1】:

    是的,你可以通过 jQuery 来完成。我能够这样做,但它需要一些额外的 javascript 工作。我将通过简单的例子展示我如何解决这种情况的大致思路。

    首先让我们假设我们有一些对象要传输。没什么特别的。

    SomeDto.java

    public class SomeDto {
    
        private String fieldA;
        private String fieldB;
    
        // Getters and Setters
    }
    

    其次,让我们有一些具有后期功能的标准控制器来执行此操作。我比平时添加了“额外”的两件事是接受 json 请求正文内容和返回片段。

    SomeController.class

    @RequestMapping(path = "/some/endpoint", 
                    method = ReqestMethod.POST, 
                    consumes = "application/json; charset=utf-8")
    public String postSomeData(@RequestBody SomeDto someDto) {
    
        // some action on passed object
    
        return "some/view :: some-fragment"
    }
    

    然后我们有一个带有片段的 html 文件。这里的技巧是我们通过 jQuery ajax 异步发布数据,等待响应并用这个响应替换片段(因为我们应该收到重新渲染的片段)。

    some/view.html

    <!-- Provide id to your fragment element, so that it can be referenced from js -->
    <div id="some-fragment" th:fragment="some-fragment">
    
        <!-- Some rendered data. Omitted -->
    
        <!-- 
            Don't provide neither action nor method to form,
            cause we don't want to trigger page reload 
        -->
         <form>
            <label for="fieldA">Some field</label>
            <input id="fieldA" type="text" /><br />
            <label for="fieldA">Some field</label>
            <input id="fieldA" type="text" /><br />
    
            <!-- onclick calls function that performs post -->
            <button type="button" onclick="performPost()">Submit</button>
         </form>
    </div>
    
    <!-- 
        Script with logic of ajax call. Should be outside updated fragment.
        Use th:inline so that you could take advantage of thymeleaf's data integrating
    -->
    <script th:inline="javascript">
    
        performPost = function() {
    
            /* Prepare data that have to be send */
            var data = {};
            data.fieldA = $('#fieldA').val();
            data.fieldB = $('#fieldB').val();
    
            /* Prepare ajax post settings */
            var settings = {
    
                /* Set proper headers before send */ 
                beforeSend: function(xhr, options) {
    
                    /* Provide csrf token, otherwise backend returns 403. */
                    xhr.setRequestHeader("X-CSRF-TOKEN", [[ ${_csrf.token} ]]);
    
                    /* Send json content */
                    xhr.setRequestHeader("content-type" ,"application/json; charset=utf-8");
                },
                type: 'POST',
                url: [[ @{/some/endpoint} ]],
                data: JSON.stringify(data)
            }
    
            /* Send request to backend with above settings and provide success callback */
            $.ajax(settings).done(function(result) {
    
                /* 
                    Replace your fragment with newly rendered fragment. 
                    Reference fragment by provided id
                */
                $('#some-fragment').html(result);
            });
        }
    
    </script>
    

    就是这样。我希望这会对你有所帮助。如果我找到一些时间,我将尝试使用您的用例检查此解决方案并更新答案。

    【讨论】:

      猜你喜欢
      • 2018-07-31
      • 2021-07-28
      • 2016-05-06
      • 2013-04-07
      • 1970-01-01
      • 2016-01-22
      • 2011-09-13
      • 2015-11-25
      • 1970-01-01
      相关资源
      最近更新 更多