You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用jQuery实现点击按钮后重新调用Dropzone的init函数?

问题

我通过for循环生成了一组结构相似的<div>元素,每个元素都配有编辑信息的按钮。点击编辑按钮会弹出一个包含Dropzone文件上传组件的模态框,我通过jQuery修改了绑定图片ID的输入框值,以此加载对应<div>的关联图片。

但现在遇到的问题是:Dropzone在页面初始加载时就已完成创建,此时输入框值为空,导致init函数无法读取后续更新的ID。我希望每次点击编辑按钮后,能以原有配置重新执行Dropzone的init函数。

相关代码片段

HTML 文件

@foreach($steps as $step)
    <div class="row card p-3 mb-3 d-flex justify-content-center">
        <div class="col-12 row justify-content-between align-self-center mb-2">
            
            <div class="col-6 p-0">
                <button type="button" class="btn update_step" title="update"
                        data-toggle="modal" data-target="#update_step_modal"
                        step_number="{{$step->number}}"
                        route="{{route('panel.contents.clusters.steps.update', [$content->id, $cluster->id, $step->id])}}">
                    <span class="mdi mdi-18px mdi-square-edit-outline"></span>
                </button>
              </div>
         </div>

         <div class="col-12 row justify-content-center align-self-center mb-2">
             <p class="col-12 step_description_p">{{$step->description}}</p>
             <div class="col-6 justify-content-center pt-4">
                 <input class="step_cover_id" value="{{$step->cover_id}}" hidden>
                 <img src="{{$step->cover_image}}">
              </div>
         </div>
    </div>      
@endforeach

模态框 HTML 文件

<div class="modal fade" id="update_step_modal" tabindex="-1" role="dialog" aria-labelledby="update_step_modal" aria-hidden="true" data-keyboard="false" data-backdrop="static">
    <div class="modal-dialog modal-dialog-centered" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>

            <div class="modal-body">
                <div class="col-12 row justify-content-center align-self-center">
                    <form action="" method="POST" id="update_step_form">
                        @method('PATCH')
                        @csrf
                        <textarea name="description" id="update_step_description"></textarea>
                        <input name="cover_id" id="update_step_cover_id" hidden>
                        <input name="video_id" id="update_step_video_id" hidden>
                    </form>
                </div>

                <div class="col-12 row justify-content-center align-self-center mb-2">
                    <div class="col-6" id="update_step_cover_div">
                        <form action="{{url('panel/upload')}}" method="POST" 
                               class="dropzone" id="update_step_cover_form">
                            @csrf
                            <input name="type" value="step_cover" hidden />
                            <input name="content_id" value="{{$content->id}}" hidden />
                            <input name="cluster_id" value="{{$cluster->id}}" hidden />
                            <div class="dz-message" data-dz-message>
                                <span class="m-dropzone__msg-desc">some messages</span>
                            </div>
                        </form>
                    </div>
                </div>

                <div class="d-flex justify-content-center">
                    <button type="button" class="btn" id="step_update_button">
                        <span class="ladda-label">update</span>
                        <span class="ladda-spinner"></span>
                    </button>
                </div>
            </div>
        </div>
    </div>
</div>

JavaScript 文件

$('.update_step').on('click', function () {
   let step_number = $(this).attr('step_number')
   let route = $(this).attr('route')

   $('#edited_step_number').text(step_number)
   $('#update_step_form').attr('action', route)

   let parent = $(this).parent().parent().parent();
   let description = parent.find('.step_description_p').text();
   let cover_id = parent.find('.step_cover_id').val();
   let video_id = parent.find('.step_video_id').val();

   $('#update_step_description').val(description).change();
   $('#update_step_cover_id').val(cover_id).change();
   $('#update_step_video_id').val(video_id).change();
});

Dropzone.options.updateStepCoverForm = {
    paramName: "file", 
    uploadMultiple: false,
    acceptedFiles: "image/*,",
    maxFiles: 1,
    headers: {
        'X-CSRF-Token': $('input[name="_token"]').val(),
        'Accept': 'application/json'
    },
    addRemoveLinks: true,
    init: function() {
        let coverDropzone = this;
        let id = $('#update_step_cover_id').val()

        if(id !== ''){
            $.ajax({
                url: '/panel/fetch_file/' + id,
                type: 'get',
                dataType: 'json',
                success: function (response) {
                    var mockFile = {name: response.data.file_name, size: response.data.size};
                    coverDropzone.emit("addedfile", mockFile);
                    coverDropzone.emit("thumbnail", mockFile, response.data.file_path);
                    coverDropzone.emit("complete", mockFile);
                    coverDropzone.options.maxFiles = 0;
                }
            });
        }

        this.on("removedfile", file => {
            let id = $('#update_step_cover_id').val()
            remove_file_function(id, "update_cover")
        });
    },
    accept: function(file, done) {
        done();
    },
    success: function (file, response) {
        $('#update_step_cover_id').val(response.data.id).change();
    },
    error: function (file, response) {
        error_function(file, response)
    }
};
解决方案

核心思路是销毁旧的Dropzone实例,每次打开模态框时重新初始化,这样init函数就能读取到最新的cover_id值。

1. 重构Dropzone配置与初始化

把自动初始化改为手动初始化,方便控制实例的生命周期:

// 定义Dropzone配置模板,复用原有配置
const coverDropzoneConfig = {
    paramName: "file", 
    uploadMultiple: false,
    acceptedFiles: "image/*", // 去掉原代码中多余的逗号
    maxFiles: 1,
    headers: {
        'X-CSRF-Token': $('input[name="_token"]').val(),
        'Accept': 'application/json'
    },
    addRemoveLinks: true,
    init: function() {
        let coverDropzone = this;
        let id = $('#update_step_cover_id').val()

        if(id !== ''){
            $.ajax({
                url: '/panel/fetch_file/' + id,
                type: 'get',
                dataType: 'json',
                success: function (response) {
                    var mockFile = {name: response.data.file_name, size: response.data.size};
                    coverDropzone.emit("addedfile", mockFile);
                    coverDropzone.emit("thumbnail", mockFile, response.data.file_path);
                    coverDropzone.emit("complete", mockFile);
                    coverDropzone.options.maxFiles = 0;
                }
            });
        }

        this.on("removedfile", file => {
            let id = $('#update_step_cover_id').val()
            remove_file_function(id, "update_cover")
        });
    },
    accept: function(file, done) {
        done();
    },
    success: function (file, response) {
        $('#update_step_cover_id').val(response.data.id).change();
    },
    error: function (file, response) {
        error_function(file, response)
    }
};

// 全局变量存储Dropzone实例
let coverDropzoneInstance = null;

2. 修改编辑按钮点击事件

在更新输入框值后,销毁旧实例并重新创建Dropzone:

$('.update_step').on('click', function () {
   let step_number = $(this).attr('step_number')
   let route = $(this).attr('route')

   $('#edited_step_number').text(step_number)
   $('#update_step_form').attr('action', route)

   let parent = $(this).parent().parent().parent();
   let description = parent.find('.step_description_p').text();
   let cover_id = parent.find('.step_cover_id').val();
   let video_id = parent.find('.step_video_id').val();

   $('#update_step_description').val(description).change();
   $('#update_step_cover_id').val(cover_id).change();
   $('#update_step_video_id').val(video_id).change();

   // 销毁旧实例并重建
   if (coverDropzoneInstance) {
       coverDropzoneInstance.destroy(); // 销毁实例
       $('#update_step_cover_form').empty(); // 清空容器内的Dropzone生成元素
   }
   // 重新初始化Dropzone
   coverDropzoneInstance = new Dropzone("#update_step_cover_form", coverDropzoneConfig);
});

3. 可选:模态框关闭时清理实例

避免模态框关闭后残留无效实例,可添加模态框关闭事件:

$('#update_step_modal').on('hidden.bs.modal', function () {
    if (coverDropzoneInstance) {
        coverDropzoneInstance.destroy();
        coverDropzoneInstance = null;
        $('#update_step_cover_form').empty();
    }
});

内容的提问来源于stack exchange,提问作者Negar Javadzadeh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 05:15:54