英文:
vue.js dropdown of autocomplete doesn't render when inside of a v-for
问题
以下是您要求的代码部分的中文翻译:
[![页面截图](https://i.stack.imgur.com/th353.png)](https://i.stack.imgur.com/th353.png)
我对Vue不太熟悉,而这个项目使用的是Vue 2.6.10。
我们有一个专有的控件,基本上是一个网络用户查找工具。
我加入了这个已经存在的项目。它是使用template.html文件和它们各自的.js文件构建的。
我有一个特定的模板文件,在其中我需要在v-for中使用我的查找控件。但我无法使下拉菜单在v-for内部呈现。如果我去掉v-for并硬编码控件(作为测试),查找下拉菜单可以正常呈现。
请看我的两个代码版本,一个是可以工作的硬编码版本,另一个是v-for版本,搜索名称后无法呈现我的下拉菜单。
我注意到两个版本之间的一个区别是,当下拉菜单正常呈现时,输入控件的类中包含了"ui-autocomplete-input",并且还包含了"autocomplete="off""。但在控件不按预期工作时,输入控件中没有这两个项。
工作版本:
```html
<template id="email-template">
<div class="container border col-md-12" style="margin-top:10px;">
<tabs style="padding-top:10px;">
<tab title="任务摘要">:
<!-- 省略部分内容 -->
</tab>
<!-- 调查电子邮件设置 -->
<tab title="调查">
<!-- 省略部分内容 -->
</tab>
</tabs>
</div>
</template>
<style scoped>
.emailGroup-header {
cursor: pointer;
}
.emailGroup-header:hover {
background-color: #E7E7E7;
}
</style>
不工作的v-for版本:
<template id="email-template">
<div class="container border col-md-12" style="margin-top:10px;">
<tabs style="padding-top:10px;">
<tab title="任务摘要">
<!-- 省略部分内容 -->
</tab>
<!-- 调查电子邮件设置 -->
<tab title="调查">
<!-- 省略部分内容 -->
</tab>
</tabs>
</div>
</template>
<style scoped>
.emailGroup-header {
cursor: pointer;
}
.emailGroup-header:hover {
background-color: #E7E7E7;
}
</style>
email.js 文件:
var emailPanel = Vue.component('email-panel', {
props: {
// id: {
// type: Number,
// },
// emailGroupMembersAllList: {
// type: Object
// },
// autoIncludeEmails: {
// type: Object
// },
},
data() {
return {
opened: [],
emailGroupMembersAllList: [],
}
},
template: '#email-template',
beforeMount() {
window.addEventListener("beforeunload", this.handlerClose);
},
beforeDestroy() {
window.removeEventListener("beforeunload", this.handlerClose);
},
mounted() {
$(".userForm").nedLookup();
this.getEmails();
},
computed: {
},
methods: {
getEmails() {
var vm = this;
//获取电子邮件(包括此页面的当前用户)并填充GroupLists/to/cc/Subject
this.getTaskSummaryEmails()
.then(data => {
vm.emailGroupMembersAllList = data.EmailGroupMembersAllList;
vm.autoIncludeEmails = data.AutoIncludeEmails;
localStorage.setItem('data', JSON.stringify(data));
})
.catch(function (error) {
console.log(error);
});
},
async getTaskSummaryEmails() {
try {
let resp;
resp = await axios.get(`/api/task/email`);
return resp.data;
} catch (error) {
console.log(error);
this.$toasted.show("检索电子邮件组时出错", { type: "error", duration: 3000 })
}
},
addNewEmailGroup() {
},
toggleEmailGroup(id) {
const index = this.opened.indexOf(id);
if (index > -1) {
this.opened.splice(index, 1)
} else {
this.opened.push(id)
}
},
tabChanged() {
if (this.$toasted != null) {
this.$toasted.clear();
}
},
handlerClose(e) {
if (this.$toasted != null) {
this.$toasted.clear();
}
},
}
})
希望这些翻译有助于解决您的问题。如果您需要进一步的帮助,请随时提出。
英文:
New to vue, and this particular project is using vue 2.6.10.
We have a proprietary control that we use which is basically a network user lookup.
I came on to this already established project. It is built using template.html files and their respective .js files.
I have this particular template file where I need a v-for with my lookup control inside. I cannot get the dropdown to render when it is inside of the v-for. If I take out the v-for and hardcode the controls (as a test), the lookup dropdowns render fine.
Please see my two versions of the code, the hardcoded one which works, and the v-for version that does not render my dropdown after a search by name.
One thing I have noticed that is a difference between the 2 versions, is that when I inspect my elements, I see that when the dropdown does render properly, the input control has ui-autocomplete-input as part of the class and also has autocomplete="off". When the control does not work as expected, those two items don't exist in the input control.
Working version:
<template id="email-template">
<div class="container border col-md-12" style="margin-top:10px;">
<tabs style="padding-top:10px;">
<tab title="Task Summary">
<table class="table userForm"> <!--class userForm must be here for nedLookup!!-->
<thead>
<tr>
<th>Email Groups</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>
<table>
<tr>
<td class="col-md-5">
<table class="table table-striped table-condensed table-bordered">
<thead>
<tr>
<th style="width: 10%">Group1 Members</th>
<th style="width: 10%; text-align: center;">AutoInclude</th>
<th style="width: 10%; text-align: center;">Delete</th>
</tr>
</thead>
<tr>
<td>user1@test.com</td>
<td>
<span style='display: block; text-align: center; padding-top: 0;'>
<label class="label" style='margin-left: 0'>
<input type="checkbox" style='margin-left: 0' checked>
</label>
</span>
</td>
<td>
<span style='display: block; text-align: center; padding-top: 0;' class='trash-icon'>
<i class='fa fa-trash' style='margin-left: 0'></i>
</span>
</td>
</tr>
<tr>
<td>user2@test.com</td>
<td>
<span style='display: block; text-align: center; padding-top: 0;'>
<label class="label" style='margin-left: 0'>
<input type="checkbox" style='margin-left: 0'>
</label>
</span>
</td>
<td>
<span style='display: block; text-align: center; padding-top: 0;' class='trash-icon'>
<i class='fa fa-trash' style='margin-left: 0'></i>
</span>
</td>
</tr>
<tr><td colspan="3"><label><input type="checkbox" name="checkbox"> AutoInclude Entire Group</label></td></tr>
</table>
</td>
<td class="col-md-4">
<input type="text" :id="Group1_userLookup"
:name="Group1_userLookup" value=""
class="nedLookup form-control"
placeholder="Search User by Last Name, FirstName" />
<!--<input id="userLookupEmail" type="hidden" data-ned="Email" />-->
</td>
<td class="col-md-2">
<button type="button" class="btn btn-primary" @click="addUserToGroup()" role="button">
Add User to Group
</button>
</td>
<td class="col-md-1">
<button type="button" class="btn btn-primary" @click="saveGroup()" role="button">
Save Group
</button>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>
<table>
<tr>
<td class="col-md-5">
<table class="table table-striped table-condensed table-bordered">
<thead>
<tr>
<th style="width: 10%">Group2 Members</th>
<th style="width: 10%; text-align: center;">AutoInclude</th>
<th style="width: 10%; text-align: center;">Delete</th>
</tr>
</thead>
<tr>
<td>user3@test.com</td>
<td>
<span style='display: block; text-align: center; padding-top: 0;'>
<label class="label" style='margin-left: 0'>
<input type="checkbox" style='margin-left: 0'>
</label>
</span>
</td>
<td>
<span style='display: block; text-align: center; padding-top: 0;' class='trash-icon'>
<i class='fa fa-trash' style='margin-left: 0'></i>
</span>
</td>
</tr>
<tr><td colspan="3"><label><input type="checkbox" name="checkbox"> AutoInclude Entire Group</label></td></tr>
</table>
</td>
<td class="col-md-4">
<input type="text" :id="Group2_userLookup"
:name="Group2_userLookup" value=""
class="nedLookup form-control"
placeholder="Search User by Last Name, FirstName" />
<input id="userLookupEmail" type="hidden" data-ned="Email" />
</td>
<td class="col-md-2">
<button type="button" class="btn btn-primary" @click="addUserToGroup()" role="button">
Add User to Group
</button>
</td>
<td class="col-md-1">
<button type="button" class="btn btn-primary" @click="saveGroup()" role="button">
Save Group
</button>
</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
<div class="text-center">
<btn type="button" class="btn btn-primary" @click="addNewEmailGroup" role="button"><i class="fa fa-plus-circle"></i> Add Email Group </btn>
</div>
</tab>
<!-- Survey Email settings-->
<tab title="Survey">
<table class="table">
<thead>
<tr>
<th>Coming Soon</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</tab>
</tabs>
</div>
</template>
<style scoped>
.emailGroup-header {
cursor: pointer;
}
.emailGroup-header:hover {
background-color: #E7E7E7;
}
</style>
Non working version with v-for:
<template id="email-template">
<div class="container border col-md-12" style="margin-top:10px;">
<tabs style="padding-top:10px;">
<tab title="Task Summary">
<table class="table userForm"> <!--class userForm must be here for nedLookup!!-->
<thead>
<tr>
<th>Email Groups</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr v-for="emailGroupMembers in emailGroupMembersAllList">
<td>
<table>
<tr>
<td class="col-md-4">
<table class="table table-striped table-condensed table-bordered">
<thead>
<tr>
<th style="width: 10%">{{emailGroupMembers.EmailGroup.GroupName}} Members</th>
<th style="width: 10%; text-align: center;">AutoInclude</th>
<th style="width: 10%; text-align: center;">Delete</th>
</tr>
</thead>
<tr v-for="user in emailGroupMembers.EmailGroup.EmailGroupUsers">
<td>{{user.Email}}</td>
<td>
<span style='display: block; text-align: center; padding-top: 0;'>
<label class="label" style='margin-left: 0'>
<input type="checkbox" style='margin-left: 0' checked>
</label>
</span>
</td>
<td>
<span style='display: block; text-align: center; padding-top: 0;' class='trash-icon'>
<i class='fa fa-trash' style='margin-left: 0'></i>
</span>
</td>
</tr>
</table>
</td>
<td class="col-md-4">
<input type="text" :id="emailGroupMembers.EmailGroup.GroupName + '_userLookup'"
:name="emailGroupMembers.EmailGroup.GroupName + '_userLookup'" value=""
class="nedLookup form-control"
placeholder="Last Name, FirstName" />
<!--<input id="userLookupEmail" type="hidden" data-ned="Email" />-->
</td>
<td class="col-md-2">
<button type="button" class="btn btn-primary" @click="addUserToGroup()" role="button">
Add User to Group
</button>
</td>
<td class="col-md-2">
<button type="button" class="btn btn-primary" @click="saveGroup()" role="button">
Save Group
</button>
</td>
</tr>
</table>
</td>
</tr>
<!--<tr>
<td>
<table>
<tr>
<td class="col-md-4">
<table class="table table-striped table-condensed table-bordered">
<thead>
<tr>
<th style="width: 10%">Group2 Members</th>
<th style="width: 10%; text-align: center;">AutoInclude</th>
<th style="width: 10%; text-align: center;">Delete</th>
</tr>
</thead>
<tr>
<td>karrie.klein@saic.com</td>
<td>
<span style='display: block; text-align: center; padding-top: 0;'>
<label class="label" style='margin-left: 0'>
<input type="checkbox" style='margin-left: 0'>
</label>
</span>
</td>
<td>
<span style='display: block; text-align: center; padding-top: 0;' class='trash-icon'>
<i class='fa fa-trash' style='margin-left: 0'></i>
</span>
</td>
</tr>
</table>
</td>
<td class="col-md-4">
<input type="text" :id="Group2_userLookup"
:name="Group2_userLookup" value=""
class="nedLookup form-control"
placeholder="Last Name, FirstName" />
<input id="userLookupEmail" type="hidden" data-ned="Email" />
</td>
<td class="col-md-2">
<button type="button" class="btn btn-primary" @click="addUserToGroup()" role="button">
Add User to Group
</button>
</td>
<td class="col-md-2">
<button type="button" class="btn btn-primary" @click="saveGroup()" role="button">
Save Group
</button>
</td>
</tr>
</table>
</td>
</tr>-->
</tbody>
</table>
<div class="text-center">
<btn type="button" class="btn btn-primary" @click="addNewEmailGroup" role="button"><i class="fa fa-plus-circle"></i> Add Email Group </btn>
</div>
</tab>
<!-- Survey Email settings-->
<tab title="Survey">
<table class="table">
<thead>
<tr>
<th>Coming Soon</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</tab>
</tabs>
</div>
</template>
<style scoped>
.emailGroup-header {
cursor: pointer;
}
.emailGroup-header:hover {
background-color: #E7E7E7;
}
</style>
email.js file:
var emailPanel = Vue.component('email-panel', {
props: {
// id: {
// type: Number,
// },
// emailGroupMembersAllList: {
// type: Object
// },
// autoIncludeEmails: {
// type: Object
// },
},
data() {
return {
opened: [],
emailGroupMembersAllList: [],
}
},
template: '#email-template',
beforeMount() {
window.addEventListener("beforeunload", this.handlerClose);
},
beforeDestroy() {
window.removeEventListener("beforeunload", this.handlerClose);
},
mounted() {
$(".userForm").nedLookup();
this.getEmails();
},
computed: {
},
methods: {
getEmails() {
var vm = this;
//go get emails (including current user of this page) and fill GroupLists/to/cc/Subject
this.getTaskSummaryEmails()
.then(data => {
vm.emailGroupMembersAllList = data.EmailGroupMembersAllList;
vm.autoIncludeEmails = data.AutoIncludeEmails;
localStorage.setItem('data', JSON.stringify(data));
})
.catch(function (error) {
console.log(error);
});
},
async getTaskSummaryEmails() {
try {
let resp;
resp = await axios.get(`/api/task/email`);
return resp.data;
} catch (error) {
console.log(error);
this.$toasted.show("There was an error retrieving the email groups", { type: "error", duration: 3000 })
}
},
addNewEmailGroup() {
},
toggleEmailGroup(id) {
const index = this.opened.indexOf(id);
if (index > -1) {
this.opened.splice(index, 1)
} else {
this.opened.push(id)
}
},
tabChanged() {
if (this.$toasted != null) {
this.$toasted.clear();
}
},
handlerClose(e) {
if (this.$toasted != null) {
this.$toasted.clear();
}
},
}
})
I have searched and not found anything matching my particular issue with this old version of vue.js
I have found suggestions regarding using the :key. I am not moving things around, so I don't believe I need the :key, but I tried it anyway to no avail.
答案1
得分: 0
我觉得你在这行缺少了`key`:
```vuejs
<tr v-for="emailGroupMembers in emailGroupMembersAllList">
尝试:
<tr v-for="(emailGroupMembers, index) in emailGroupMembersAllList" :key="index">
英文:
I think you're missing the key
on this line:
<tr v-for="emailGroupMembers in emailGroupMembersAllList">
Try:
<tr v-for="(emailGroupMembers, index) in emailGroupMembersAllList" :key="index">
答案2
得分: 0
我只会翻译代码的部分,以下是翻译后的代码:
Well, just going back to basics, I added an eventhandler for an outer static element and that solved the issue.
mounted() {
this.getEmails();
// 在这里为我们动态添加的nedLookups创建事件代理
// 必须为已经存在于DOM中且包含我们的nedLookup的元素添加事件监听器
document.getElementById("emailGroupsTable").addEventListener("click", function (e) {
if (e.target.nodeName == 'INPUT') { // 这是一个nedLookup元素
$(".userForm").nedLookup();
}
});
},
希望这有所帮助。如果您需要进一步的翻译或有其他问题,请随时提出。
英文:
Well, just going back to basics, I added an eventhandler for an outer static element and that solved the issue.
mounted() {
this.getEmails();
//Creating event delegate here for our dynamically added nedLookups
//have to add event listener to element that is already in the DOM and that contains our nedLookup
document.getElementById("emailGroupsTable").addEventListener("click", function (e) {
if (e.target.nodeName == 'INPUT') { //this is one of the nedLookup elements
$(".userForm").nedLookup();
}
});
},
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论