如何用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">×</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
相关产品推荐
相关产品推荐

