admin管理员组文章数量:1386782
I have a grid created with vue.js, but I've having difficulty getting the right index for the values after a keyword filter is applied.
<tbody v-for="
entry in data
| filterBy filterKey
| orderBy sortKey sortOrders[sortKey]">
<tr v-if="$index == 0 || ($index > 0 && entry['value'] != data[$index-1]['value'])">
<td class="Header" colspan="3">
VALUE: @{{{entry["value"]}}}
</td>
</tr>
...
In this case, {{$index}} gives 0, 1, 2, 3 etc. However, when a filter is applied, only parts of the data are visible on-screen. (i.e. only the entries at indexes 6 and 8) Unfortunately, $index is still incrementing by 1 starting at 0, making it impossible to reference the previous entry. What is the correct way to reference the previous entry?
(I want to check if a certain part of the entry is different than the one above it, and if it is, create a new header. I have it working except for when a keyword filter is applied)
I have a grid created with vue.js, but I've having difficulty getting the right index for the values after a keyword filter is applied.
<tbody v-for="
entry in data
| filterBy filterKey
| orderBy sortKey sortOrders[sortKey]">
<tr v-if="$index == 0 || ($index > 0 && entry['value'] != data[$index-1]['value'])">
<td class="Header" colspan="3">
VALUE: @{{{entry["value"]}}}
</td>
</tr>
...
In this case, {{$index}} gives 0, 1, 2, 3 etc. However, when a filter is applied, only parts of the data are visible on-screen. (i.e. only the entries at indexes 6 and 8) Unfortunately, $index is still incrementing by 1 starting at 0, making it impossible to reference the previous entry. What is the correct way to reference the previous entry?
(I want to check if a certain part of the entry is different than the one above it, and if it is, create a new header. I have it working except for when a keyword filter is applied)
Share Improve this question asked May 16, 2016 at 23:22 SkeetsSkeets 4,8583 gold badges48 silver badges73 bronze badges 4-
so when you say "previous" you mean "previous in
this.data
", instead of the items being filtered and shown? – Raj Kamal Commented May 17, 2016 at 5:52 - For example, out of 8 entries only 2 show up with a filter. In that case, this for loop happens twice. Although the 2 items shown are actually numbers 6 and 8, the index variable only has 0 and 1. Within the 2nd iteratuon of the loop, I need to find a way to reference the 'entry' in the previous iteration of the loop. So not the previous in the data variable, the previous in the data being filtered and shown is what I want. – Skeets Commented May 17, 2016 at 6:46
-
I see, for that you need to keep an array
prev
and updateprevious
values whenever value changes. Best way to do it is to warpdata | filter | sort
in a puted property and$watch
the puted property for changes reference for $watch and puted property. I will try to make a jsfiddle for clarity. – Raj Kamal Commented May 17, 2016 at 8:19 - That sounds great! I'll try it out, but I'm new to vue.js so a jsfiddle would help a lot. Thanks. – Skeets Commented May 17, 2016 at 14:57
3 Answers
Reset to default 2Here is the jsfiddle as I said
https://jsfiddle/sg4jtzzw/
The gist of it is that
A puted property is added which encapsulates filtering and sorting on this.data
puted:{
special: function(){
var key= this.filt;
return this.data.filter(function(row){
return row.indexOf(key)!= -1;
}).sort();
}
}
In ready function, we initialize a $watch
to update prev
according to value of special
ready: function(){
var self = this;
self.prev= [];
this.$watch('special',function(newVal, oldVal){
self.prev = oldVal;
});
}
Html portion is quite simplified and pact
<div v-for="item in special">
<span v-if=" previousList(item)== true"> Old </span>
{{ item }}
</div>
Note: both filter()
and sort()
are js functions, not vue functions, and are case-sensitive. The code would be less verbose if I were to use vue filters, but I don't how to. As using built-in filters is not remended approach, I don't advise using them either
To know about remended approach on filters, you can read the discussion on github
I found a solution using a custom filter to populate a filtered array that can utilize the new indexes:
add another prop for the data filtered:
data: Array,
dataFiltered: Array,
Then add a custom filter that doesn't actually filter anything, but stores the filtered array:
Vue.filter('populateFilteredData', function (filteredArray, input) {
this.dataFiltered = filteredArray;
return filteredArray;
});
make sure this filter is used AFTER all other filters and sorts:
<tbody v-for="
entry in data
| filterBy filterKey
| orderBy sortKey sortOrders[sortKey]
| populateFilteredData
">
then the filtered array can be used to access information from previous iterations of the v-for loop like this:
{{{ dataFiltered[$index-1] }}}
That took quite some time to figure out and was really counter-intuitive. If anyone knows a better way (that is still concise and simple) to acplish the same thing, please post your answer!
Just thought I'd mention this, in case it could assist anyone. Don't forget the power of just specifically referencing the array you're iterating through by its index and manually grabbing values in if statements, rather than writing contrived loop methods. For example:
<div class="schedule-data-container" :class="{roundShift: i==0 || schedules[i-(i>1 ? 1 : 0)].round < s.round}" v-for="(s,i) in schedules" :key="i">
<div class="roundNumber" v-if="i==0 || schedules[i-(i>1 ? 1 : 0)].round < s.round">
Round {{ s.round }}
</div>
</div>
本文标签: javascriptReference previous value in vfor in vuejsStack Overflow
版权声明:本文标题:javascript - Reference previous value in v-for in vue.js - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744507536a2609677.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论