vuejs / Discussion

Vue.js discussion
167 stars 17 forks source link

[HELP] filtered data length #387

Closed oleynikd closed 9 years ago

oleynikd commented 9 years ago

Hi,

I'm using Vue for displaying search results. Everything is super cool! For search results output I use:

<li v-repeat="item in channels | filterBy searchText in 'name'">{{ item.name }}</li>

channels is array like:

[
   {"name": "name1", "icon": false},
   {"name": "name2", "icon": false}
]

Works great!

But I need to make this lis selectable by up/down keys (a common task for search lists). I use this:

v-on="
    keydown: selectedItem-- | key 'up',
    keydown: selectedItem++ | key 'down'
"

And on repeat model I add v-class:

<li v-repeat="item in channels | filterBy searchText in 'name'" v-class="selected: selectedItem == $index">{{ item.name }}</li>

This also works, but:

  1. How can I know that selectedItem has reached the end of the list? How can I know the length of filtered array?
  2. How can I get currently selected item from list to handle ENTER key down on it?

Thanks.

yyx990803 commented 9 years ago

If you need to access a filtered result, it's often better to use a computed property:

computed: {
  filteredChannels: function () {
    var filter = Vue.filter('filterBy')
    return filter(this.channels, this.searchText, 'name')
  }
}

Then in your template, work with filteredChannels directly.

For the enter key, just retrieve the item as this.filteredChannels[this.selectedItem].

oleynikd commented 9 years ago

Great! Thank you A LOT!!!

oleynikd commented 9 years ago

In case someone will try this, there's a little typo in @yyx990803 response. The right version is:

computed: {
  filteredChannels: function () {
    var filter = Vue.filter('filterBy')
    return filter(this.channels, this.searchText, 'name')
  }
}

Thank you once more! Worked like super magic!

yyx990803 commented 9 years ago

oops, fixed typo ;)

oleynikd commented 9 years ago

Dear @yyx990803 is it a god idea to recreate var filter everytime? Or this closure is called only once? Thanks.

yyx990803 commented 9 years ago

@oleynikd it's fine, the cost is negligible.

jillztom commented 9 years ago

How can I get the length of an array and display it in the View. Something like

<span v-text="users.length"></span>
jillztom commented 9 years ago

I think I found a solution:

filters:{
   count: function(value){
      return value.length;
    }
}

and in view:

<span v-text="users | count"></span>

This worked for me. Thanks :)