Skip to content

Commit 393a4e2

Browse files
committed
v-repeat object first pass, value -> $value
1 parent 9482e51 commit 393a4e2

File tree

4 files changed

+54
-12
lines changed

4 files changed

+54
-12
lines changed

src/compiler.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,11 @@ function Compiler (vm, options) {
9898
// observe the data
9999
compiler.observeData(data)
100100

101-
// for repeated items, create an index binding
102-
// which should be inenumerable but configurable
101+
// for repeated items, create index/key bindings
102+
// because they are ienumerable
103103
if (compiler.repeat) {
104-
//data.$index = compiler.repeatIndex
105-
def(data, '$index', compiler.repeatIndex, false, true)
106104
compiler.createBinding('$index')
105+
if (data.$key) compiler.createBinding('$key')
107106
}
108107

109108
// now parse the DOM, during which we will create necessary bindings

src/directives/repeat.js

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ var Observer = require('../observer'),
22
utils = require('../utils'),
33
config = require('../config'),
44
transition = require('../transition'),
5+
def = utils.defProtected,
56
ViewModel // lazy def to avoid circular dependency
67

78
/**
@@ -77,6 +78,35 @@ var mutationHandlers = {
7778
}
7879
}
7980

81+
/**
82+
* Convert an Object to a v-repeat friendly Array
83+
*/
84+
function objectToArray (obj) {
85+
var res = [], val, data
86+
for (var key in obj) {
87+
val = obj[key]
88+
data = utils.typeOf(val) === 'Object'
89+
? val
90+
: { $value: val }
91+
def(data, '$key', key, false, true)
92+
res.push(data)
93+
}
94+
return res
95+
}
96+
97+
/**
98+
* Find an object or a wrapped data object
99+
* from an Array
100+
*/
101+
function indexOf (arr, obj) {
102+
for (var i = 0, l = arr.length; i < l; i++) {
103+
if (arr[i] === obj || (obj.$value && arr[i].$value === obj.$value)) {
104+
return i
105+
}
106+
}
107+
return -1
108+
}
109+
80110
module.exports = {
81111

82112
bind: function () {
@@ -119,6 +149,12 @@ module.exports = {
119149
},
120150

121151
update: function (collection, init) {
152+
153+
if (utils.typeOf(collection) === 'Object') {
154+
this.object = collection
155+
collection = objectToArray(collection)
156+
def(this.object, '$repeater', collection, false, true)
157+
}
122158

123159
if (collection === this.collection) return
124160

@@ -204,9 +240,9 @@ module.exports = {
204240
if (data) {
205241

206242
if (this.old) {
207-
i = this.old.indexOf(data)
243+
i = indexOf(this.old, data)
208244
}
209-
245+
210246
if (i > -1) { // existing, reuse the old VM
211247

212248
item = this.oldVMs[i]
@@ -227,8 +263,10 @@ module.exports = {
227263
// wrap primitive element in an object
228264
if (utils.typeOf(data) !== 'Object') {
229265
primitive = true
230-
data = { value: data }
266+
data = { $value: data }
231267
}
268+
// define index
269+
def(data, '$index', index, false, true)
232270

233271
}
234272

@@ -250,7 +288,6 @@ module.exports = {
250288
data: data,
251289
compilerOptions: {
252290
repeat: true,
253-
repeatIndex: index,
254291
parentCompiler: this.compiler,
255292
delegator: ctn
256293
}
@@ -265,7 +302,7 @@ module.exports = {
265302
// for primitive values, listen for value change
266303
if (primitive) {
267304
data.__observer__.on('set', function (key, val) {
268-
if (key === 'value') {
305+
if (key === '$value') {
269306
col[item.$index] = val
270307
}
271308
})

src/observer.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,12 @@ function watchArray (arr) {
131131
*/
132132
function convert (obj, key) {
133133
var keyPrefix = key.charAt(0)
134-
if ((keyPrefix === '$' || keyPrefix === '_') && key !== '$index') {
134+
if (
135+
(keyPrefix === '$' || keyPrefix === '_') &&
136+
key !== '$index' &&
137+
key !== '$key' &&
138+
key !== '$value'
139+
) {
135140
return
136141
}
137142
// emit set on bind

test/functional/fixtures/repeated-primitive.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
<div id="test">
2-
<p v-repeat="numbers" v-on="click: value+=' modified'">{{value}}</p>
2+
<p v-repeat="numbers" v-on="click: $value+=' modified'">{{$value}}</p>
33
</div>
44

55
<script src="../../../dist/vue.js"></script>
66
<script>
7+
Vue.config('debug', true)
78
var numbers = [1, 2, 'text']
8-
new Vue({
9+
var test = new Vue({
910
el: '#test',
1011
data: {
1112
numbers: numbers

0 commit comments

Comments
 (0)