Dropzone 实例适用于第一个元素但不适用于克隆元素(Vue)
Dropzone instance works on first element but not cloned elements (Vue)
我在下面有一个片段,它基本上是我目前的整个代码块,它基本上创建了一个 div,当你点击“添加另一个区域”时,它会克隆那个 div。这允许用户输入多行信息,每行都有自己的结果和图像。
问题是,由于我的卡设置,我成功地克隆了所有具有自己独特身份的东西。但是,dropzone 没有复制。第一个文件 dropzone 表单可以完美运行,但是当我克隆 div 并在页面上有 2 个或更多 dropzone 实例时,它们不起作用(它们不显示上传图像文本或任何内容)
如何才能将相同的逻辑成功应用到此处的 dropzone 实例?
new Vue({
components: {},
el: "#commonNameDiv",
data() {
return {
searchString: [''],
results: [],
savedAttributes: [],
cards: [],
showList: false,
zoneNumber:[],
imageZoneNames: [] }
},
methods: {
autoComplete(ev, card) {
this.results = [];
console.log(this.searchString);
if (ev.target.value.length > 2) {
axios.get('/product/parts/components/search', {
params: {
searchString: ev.target.value
}
}).then(response => {
card.results = response.data;
this.showList = true;
console.log(this.results);
console.log(this.searchString);
});
}
},
saveAttribute(result, card) {
card.value = result.attribute_value;
card.results = [];
card.zone = this.zoneNumber;
this.showList = false;
},
addCard: function() {
this.cards.push({
index: "",
value: "",
zoneNumber: "",
results: [],
componentImage:""
});
console.log(this.cards);
},
hideDropdown() {
this.showList = false;
},
},
created() {
this.addCard();
let instance = this;
Dropzone.options = {
maxFilesize: 12,
renameFile: function (file) {
var dt = new Date();
var time = dt.getTime();
return time + file.name;
},
acceptedFiles: ".jpeg,.jpg,.png,.gif",
addRemoveLinks: true,
timeout: 50000,
removedfile: function (file) {
console.log(file.upload.filename);
var name = file.upload.filename;
var fileRef;
return (fileRef = file.previewElement) != null ?
fileRef.parentNode.removeChild(file.previewElement) : void 0;
},
init: function() {
this.on("addedfile",
function(file) {
instance.imageZoneNames.push({name: file.upload.filename, desc: 'Line Drawing'});
console.log(file);
console.log(instance.imageZoneNames);
});
}
};
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"> </script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.5.0/dropzone.js"></script>
<div id="commonNameDiv">
<div class="uk-grid" v-for="(card, i) in cards" :key="i">
<div class="uk-width-1-10" >
<input v-model=" card.zoneNumber" size="4" type="text" name="mapNumber">
</div>
<div class="uk-width-6-10">
<input
style="width:100%"
placeholder="what are you looking for?"
v-model="card.value"
v-on:keyup="autoComplete($event, card)"
>
<div v-if="showList" class="panel-footer componentList" v-if="card.results.length">
<ul>
<li v-for="(result, i) in card.results" :key="i">
<a v-on:click="saveAttribute(result, card)">@{{ result.attribute_value }}</a>
</li>
</ul>
</div>
</div>
<div class="uk-width-3-10">
<form method="post" action="{{url('product/parts/upload/store')}}" enctype="multipart/form-data"
class="dropzone">
</form>
</div>
</div>
<div style="height: 35px;">
</div>
<div>
<a v-on:click="addCard">Add another zone</a>
</div>
</div>
实际上正在创建,但Dropzone并未重建。
我认为您必须创建一个新的 Dropzone 实例。
如果您尝试插入:
created() {
this.addCard();
var myDropzone = new Dropzone('.dropzone')
let instance = this;
Dropzone.options.myDropzone = {
甚至将选项添加到 addCard
方法或设置一个 setupDropzones
方法并将其添加到 addCard
方法。
当您实例化 Dropzone class 时,它会自动查找要在 dropzones 中转换的元素(默认情况下,具有 .dropzone
class 的元素)。
您似乎想要动态添加作为拖放区的元素。然后你需要自己触发dropzone转换。
我建议您禁用 autoDiscover
选项,并手动指定要转换为拖放区的每个元素:
addCard() {
this.cards.push({
...
});
let cardIndex = this.cards.length - 1;
// Waiting for the element #dropzone-X to exist in DOM
Vue.nextTick(function () {
new Dropzone("#dropzone-"+cardIndex, {
...
});
});
},
created() {
...
Dropzone.autoDiscover = false
// no new Dropzone()
...
// Starting setup
this.addCard();
},
<form ... class="dropzone" v-bind:id="'dropzone-'+i">
工作jsbin
有几种方法可以select转换元素($refs, ids, classes),这里我建议使用ids。
我在下面有一个片段,它基本上是我目前的整个代码块,它基本上创建了一个 div,当你点击“添加另一个区域”时,它会克隆那个 div。这允许用户输入多行信息,每行都有自己的结果和图像。
问题是,由于我的卡设置,我成功地克隆了所有具有自己独特身份的东西。但是,dropzone 没有复制。第一个文件 dropzone 表单可以完美运行,但是当我克隆 div 并在页面上有 2 个或更多 dropzone 实例时,它们不起作用(它们不显示上传图像文本或任何内容)
如何才能将相同的逻辑成功应用到此处的 dropzone 实例?
new Vue({
components: {},
el: "#commonNameDiv",
data() {
return {
searchString: [''],
results: [],
savedAttributes: [],
cards: [],
showList: false,
zoneNumber:[],
imageZoneNames: [] }
},
methods: {
autoComplete(ev, card) {
this.results = [];
console.log(this.searchString);
if (ev.target.value.length > 2) {
axios.get('/product/parts/components/search', {
params: {
searchString: ev.target.value
}
}).then(response => {
card.results = response.data;
this.showList = true;
console.log(this.results);
console.log(this.searchString);
});
}
},
saveAttribute(result, card) {
card.value = result.attribute_value;
card.results = [];
card.zone = this.zoneNumber;
this.showList = false;
},
addCard: function() {
this.cards.push({
index: "",
value: "",
zoneNumber: "",
results: [],
componentImage:""
});
console.log(this.cards);
},
hideDropdown() {
this.showList = false;
},
},
created() {
this.addCard();
let instance = this;
Dropzone.options = {
maxFilesize: 12,
renameFile: function (file) {
var dt = new Date();
var time = dt.getTime();
return time + file.name;
},
acceptedFiles: ".jpeg,.jpg,.png,.gif",
addRemoveLinks: true,
timeout: 50000,
removedfile: function (file) {
console.log(file.upload.filename);
var name = file.upload.filename;
var fileRef;
return (fileRef = file.previewElement) != null ?
fileRef.parentNode.removeChild(file.previewElement) : void 0;
},
init: function() {
this.on("addedfile",
function(file) {
instance.imageZoneNames.push({name: file.upload.filename, desc: 'Line Drawing'});
console.log(file);
console.log(instance.imageZoneNames);
});
}
};
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"> </script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.5.0/dropzone.js"></script>
<div id="commonNameDiv">
<div class="uk-grid" v-for="(card, i) in cards" :key="i">
<div class="uk-width-1-10" >
<input v-model=" card.zoneNumber" size="4" type="text" name="mapNumber">
</div>
<div class="uk-width-6-10">
<input
style="width:100%"
placeholder="what are you looking for?"
v-model="card.value"
v-on:keyup="autoComplete($event, card)"
>
<div v-if="showList" class="panel-footer componentList" v-if="card.results.length">
<ul>
<li v-for="(result, i) in card.results" :key="i">
<a v-on:click="saveAttribute(result, card)">@{{ result.attribute_value }}</a>
</li>
</ul>
</div>
</div>
<div class="uk-width-3-10">
<form method="post" action="{{url('product/parts/upload/store')}}" enctype="multipart/form-data"
class="dropzone">
</form>
</div>
</div>
<div style="height: 35px;">
</div>
<div>
<a v-on:click="addCard">Add another zone</a>
</div>
</div>
实际上正在创建,但Dropzone并未重建。 我认为您必须创建一个新的 Dropzone 实例。
如果您尝试插入:
created() {
this.addCard();
var myDropzone = new Dropzone('.dropzone')
let instance = this;
Dropzone.options.myDropzone = {
甚至将选项添加到 addCard
方法或设置一个 setupDropzones
方法并将其添加到 addCard
方法。
当您实例化 Dropzone class 时,它会自动查找要在 dropzones 中转换的元素(默认情况下,具有 .dropzone
class 的元素)。
您似乎想要动态添加作为拖放区的元素。然后你需要自己触发dropzone转换。
我建议您禁用 autoDiscover
选项,并手动指定要转换为拖放区的每个元素:
addCard() {
this.cards.push({
...
});
let cardIndex = this.cards.length - 1;
// Waiting for the element #dropzone-X to exist in DOM
Vue.nextTick(function () {
new Dropzone("#dropzone-"+cardIndex, {
...
});
});
},
created() {
...
Dropzone.autoDiscover = false
// no new Dropzone()
...
// Starting setup
this.addCard();
},
<form ... class="dropzone" v-bind:id="'dropzone-'+i">
工作jsbin
有几种方法可以select转换元素($refs, ids, classes),这里我建议使用ids。