简体   繁体   中英

Dynamic binding of v-model inside v-for loop

I'm trying to dynamically bind v-model to an object property inside of array of objects . I don't know how to do this. The goal is to select user via Select html tag and then print list of user's permissions (from array of objects ) to have a possibility to change true/false using checkboxes and save changes to object property inside of array of object .

Template:

<div id="app">
  <select v-model="selectedUser">
  <option value="" disabled>Select User</option>
    <option v-for="user in users" :value="user.name">{{ user.name }}</option>
  </select>
  <p>User Index: {{ getUserIndex }}</p>
  <ul v-if="getUserIndex !== null">
    <li v-for="(perm, id) in users[getUserIndex].perms">
      <span>{{ perm.status }}</span>
      <input type="checkbox" v-model="">
    </li>
  </ul>
</div>

script

new Vue({
  el: "#app",
  data: {
    users: [
    { name: 'Alex', perms: [ 
        { status: 'active', perm: false },
      { status: 'invoice', perm: false }
      ] },
    { name: 'John', perms: [ 
        { status: 'active', perm: false },
      { status: 'invoice', perm: false }
      ] },
    { name: 'Helen', perms: [ 
        { status: 'active', perm: false },
      { status: 'invoice', perm: false }
      ] },  
    ],
    selectedUser: ''
  },
  computed: {
    getUserIndex() {
        let username = this.selectedUser;
        let index = this.users.findIndex(el => el.name === username);
      if (index == -1) {
        return null
      } else { return index }
    }
  },
})

I share this JSFiddle link because I find it difficult to explain in words.

https://jsfiddle.net/sgtmadcap/49bjwahs/141/

I need to dynamically bind v-model to every users[someindex].perms.perm property to be able to change it. Later I want to upload this array to firebase database with all changes. Thank you in advance! I know this is a basic thing but any help is highly appreciated! PS Sorry for my bad english.

In your case <input type="checkbox" v-model="perm.perm"> is enough to make it work.

I would suggest a bit of refactoring and renaming though, sinde perm.perm shows how unintuitive your current data structure and naming is.

I'd suggest to use a computed property to return the userPermissions instead of accessing the array by index in the template.
Also consider renaming your object properties to something like permissions and isAllowed to be more clear.

computed: {
  ...
  userPermissions() {
    let index = this.getUserIndex()
    // TODO: handle null
    return this.users[index].permissions
  }
}

And in your template

<li v-for="p in userPermissions">
  <span>{{ p.status }}</span>
  <input type="checkbox" v-model="p.isAllowed">
</li>

This should works.

 new Vue({ el: "#app", data: { users: [{ name: 'Alex', perms: [{ status: 'active', perm: false }, { status: 'invoice', perm: false } ] }, { name: 'John', perms: [{ status: 'active', perm: false }, { status: 'invoice', perm: false } ] }, { name: 'Helen', perms: [{ status: 'active', perm: false }, { status: 'invoice', perm: false } ] }, ], selectedUser: '' }, computed: { getUserIndex() { let username = this.selectedUser; let index = this.users.findIndex(el => el.name === username); if (index == -1) { return null } else { return index } } }, })
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="app"> <select v-model="selectedUser"> <option value="" disabled>Select User</option> <option v-for="user in users" :value="user.name">{{ user.name }}</option> </select> <p>User Index: {{ getUserIndex }}</p> <ul v-if="getUserIndex !== null "> <li v-for="(item, id) in users[getUserIndex].perms"> <span>{{ item.status }}</span> <input type="checkbox" v-model="item.perm"> </li> </ul> </div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM