多个动态初始化时只有一个 Dropzone 工作
Only one Dropzone working when multiple dinamically initialized
我正在编写一个 Web 应用程序,我需要根据服务器内容初始化多个 dropzones,我目前有一个类似于这样的代码:
<script src="/js/dropzone.min.js"></script>
<script>
Dropzone.autoDiscover = false;
window.dropzones = {};
function checkDropzones(container) {
var possibleDropzones = container.querySelectorAll('.needs-to-be-dropzoned');
possibleDropzones.forEach(function (zone) {
if (zone.id.length === 0) {
zone.id = 'dropzone_filled_' + (new Date()).getTime();
window.dropzones[zone.id] = new Dropzone(
'#' + zone.id,
{
paramName: 'image',
addRemoveLinks: true,
}
);
}
})
}
function renderServerContent() {
window.customSections.forEach(function (custom_section) {
var container = document.getElementById(custom_section);
$.ajax({
method: 'GET',
url: '/customRenderUrl?section=' + custom_section,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
success: function (response) {
container.innerHTML = container.innerHTML + response.component;
if (response.component_type === 'image_uploader') {
checkDropzones(container);
}
// ... other marginal stuff ...
},
dataType: 'json'
})
})
}
// ... other scripts ...
window.customSections = [/* server stuff */];
renderServerContent();
</script>
基本上,我有一些东西要从服务器动态呈现,所以我发送一个请求来询问组件呈现的数据,当我得到答复时,我检查插入的内容是否包含带有 [=13 的元素=],如果是这样,我为其分配一个基于时间的 ID(组件渲染在每个组件之间有延迟,因此 ID 是唯一的)并实例化 dropzone。这仅适用于一个拖放区,但当多个拖放区位于同一页面上时,它不会产生错误,但仅适用于页面上的最后一个元素。
服务器内容是这样的:
<form
class="col-12 container-fluid pb-2 dropzone needs-to-be-dropzoned"
method="POST"
action="/imageUploadUrl"
>
<input type="hidden" name="_token" value="..." >
<div class="dz-default dz-message">
Upload files
</div>
<div class="fallback">
<input name=image" type="file" />
</div>
</form>
如果我启动 console.dir(window.dropzones)
我得到 2 个对象:
Object { dropzone_filled_1624370363574: {…}, dropzone_filled_1624370363803: {…} }
dropzone_filled_1624370363574: Object { element: form#dropzone_filled_1624370363574.col-12.container-fluid.pb-2.dropzone.needs-to-be-dropzoned.dz-clickable, version: "5.9.2", clickableElements: (1) […], … }
dropzone_filled_1624370363803: Object { element: form#dropzone_filled_1624370363803.col-12.container-fluid.pb-2.dropzone.needs-to-be-dropzoned.dz-clickable, version: "5.9.2", clickableElements: (1) […], … }
我做错了什么或遗漏了什么?
我做了各种尝试来解决这个问题,最后,我通过将所有服务器调用包装到 promises 中来修复它,等待所有 promises 解决,然后才检查 dropzones。代码大概是这样的:
<script src="/js/dropzone.min.js"></script>
<script>
Dropzone.autoDiscover = false;
window.dropzones = {};
window.containersToCheck = [];
function checkDropzones(container) {
var possibleDropzones = container.querySelectorAll('.needs-to-be-dropzoned');
possibleDropzones.forEach(function (zone) {
if (zone.id.length === 0) {
zone.id = 'dropzone_filled_' + (new Date()).getTime();
window.dropzones[zone.id] = new Dropzone(
'#' + zone.id,
{
paramName: 'image',
addRemoveLinks: true,
}
);
}
})
}
function renderServerContent() {
return new Promise(function(resolve, reject) {
window.customSections.forEach(function (custom_section) {
var container = document.getElementById(custom_section);
$.ajax({
method: 'GET',
url: '/customRenderUrl?section=' + custom_section,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
success: function (response) {
container.innerHTML = container.innerHTML + response.component;
if (response.component_type === 'image_uploader') {
window.containersToCheck.push(container);
}
resolve();
// ... other marginal stuff ...
},
dataType: 'json'
})
})
});
}
// ... other scripts ...
window.customSections = [/* server stuff */];
var promises = [];
promises.push(renderServerContent());
// other renderings
Promise.all(promises).then(function (results) {
window.containersToCheck.forEach(function(container) {
checkDropzones(container);
});
})
</script>
这样,所有 Dropzones 都可以工作。
我正在编写一个 Web 应用程序,我需要根据服务器内容初始化多个 dropzones,我目前有一个类似于这样的代码:
<script src="/js/dropzone.min.js"></script>
<script>
Dropzone.autoDiscover = false;
window.dropzones = {};
function checkDropzones(container) {
var possibleDropzones = container.querySelectorAll('.needs-to-be-dropzoned');
possibleDropzones.forEach(function (zone) {
if (zone.id.length === 0) {
zone.id = 'dropzone_filled_' + (new Date()).getTime();
window.dropzones[zone.id] = new Dropzone(
'#' + zone.id,
{
paramName: 'image',
addRemoveLinks: true,
}
);
}
})
}
function renderServerContent() {
window.customSections.forEach(function (custom_section) {
var container = document.getElementById(custom_section);
$.ajax({
method: 'GET',
url: '/customRenderUrl?section=' + custom_section,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
success: function (response) {
container.innerHTML = container.innerHTML + response.component;
if (response.component_type === 'image_uploader') {
checkDropzones(container);
}
// ... other marginal stuff ...
},
dataType: 'json'
})
})
}
// ... other scripts ...
window.customSections = [/* server stuff */];
renderServerContent();
</script>
基本上,我有一些东西要从服务器动态呈现,所以我发送一个请求来询问组件呈现的数据,当我得到答复时,我检查插入的内容是否包含带有 [=13 的元素=],如果是这样,我为其分配一个基于时间的 ID(组件渲染在每个组件之间有延迟,因此 ID 是唯一的)并实例化 dropzone。这仅适用于一个拖放区,但当多个拖放区位于同一页面上时,它不会产生错误,但仅适用于页面上的最后一个元素。
服务器内容是这样的:
<form
class="col-12 container-fluid pb-2 dropzone needs-to-be-dropzoned"
method="POST"
action="/imageUploadUrl"
>
<input type="hidden" name="_token" value="..." >
<div class="dz-default dz-message">
Upload files
</div>
<div class="fallback">
<input name=image" type="file" />
</div>
</form>
如果我启动 console.dir(window.dropzones)
我得到 2 个对象:
Object { dropzone_filled_1624370363574: {…}, dropzone_filled_1624370363803: {…} }
dropzone_filled_1624370363574: Object { element: form#dropzone_filled_1624370363574.col-12.container-fluid.pb-2.dropzone.needs-to-be-dropzoned.dz-clickable, version: "5.9.2", clickableElements: (1) […], … }
dropzone_filled_1624370363803: Object { element: form#dropzone_filled_1624370363803.col-12.container-fluid.pb-2.dropzone.needs-to-be-dropzoned.dz-clickable, version: "5.9.2", clickableElements: (1) […], … }
我做错了什么或遗漏了什么?
我做了各种尝试来解决这个问题,最后,我通过将所有服务器调用包装到 promises 中来修复它,等待所有 promises 解决,然后才检查 dropzones。代码大概是这样的:
<script src="/js/dropzone.min.js"></script>
<script>
Dropzone.autoDiscover = false;
window.dropzones = {};
window.containersToCheck = [];
function checkDropzones(container) {
var possibleDropzones = container.querySelectorAll('.needs-to-be-dropzoned');
possibleDropzones.forEach(function (zone) {
if (zone.id.length === 0) {
zone.id = 'dropzone_filled_' + (new Date()).getTime();
window.dropzones[zone.id] = new Dropzone(
'#' + zone.id,
{
paramName: 'image',
addRemoveLinks: true,
}
);
}
})
}
function renderServerContent() {
return new Promise(function(resolve, reject) {
window.customSections.forEach(function (custom_section) {
var container = document.getElementById(custom_section);
$.ajax({
method: 'GET',
url: '/customRenderUrl?section=' + custom_section,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
success: function (response) {
container.innerHTML = container.innerHTML + response.component;
if (response.component_type === 'image_uploader') {
window.containersToCheck.push(container);
}
resolve();
// ... other marginal stuff ...
},
dataType: 'json'
})
})
});
}
// ... other scripts ...
window.customSections = [/* server stuff */];
var promises = [];
promises.push(renderServerContent());
// other renderings
Promise.all(promises).then(function (results) {
window.containersToCheck.forEach(function(container) {
checkDropzones(container);
});
})
</script>
这样,所有 Dropzones 都可以工作。