@@ -6,6 +6,7 @@ import createDebuggingComment from '../../utils/createDebuggingComment';
6
6
import Expression from './shared/Expression' ;
7
7
import mapChildren from './shared/mapChildren' ;
8
8
import TemplateScope from './shared/TemplateScope' ;
9
+ import unpackDestructuring from '../../utils/unpackDestructuring' ;
9
10
10
11
export default class EachBlock extends Node {
11
12
type : 'EachBlock' ;
@@ -18,7 +19,7 @@ export default class EachBlock extends Node {
18
19
context : string ;
19
20
key : Expression ;
20
21
scope : TemplateScope ;
21
- destructuredContexts : string [ ] ;
22
+ contexts : Array < { name : string , tail : string } > ;
22
23
23
24
children : Node [ ] ;
24
25
else ?: ElseBlock ;
@@ -27,7 +28,7 @@ export default class EachBlock extends Node {
27
28
super ( compiler , parent , scope , info ) ;
28
29
29
30
this . expression = new Expression ( compiler , this , scope , info . expression ) ;
30
- this . context = info . context ;
31
+ this . context = info . context . name || 'each' ; // TODO this is used to facilitate binding; currently fails with destructuring
31
32
this . index = info . index ;
32
33
33
34
this . key = info . key
@@ -36,20 +37,19 @@ export default class EachBlock extends Node {
36
37
37
38
this . scope = scope . child ( ) ;
38
39
39
- this . scope . add ( this . context , this . expression . dependencies ) ;
40
+ this . contexts = [ ] ;
41
+ unpackDestructuring ( this . contexts , info . context , '' ) ;
42
+
43
+ this . contexts . forEach ( context => {
44
+ this . scope . add ( context . key . name , this . expression . dependencies ) ;
45
+ } ) ;
40
46
41
47
if ( this . index ) {
42
48
// index can only change if this is a keyed each block
43
49
const dependencies = this . key ? this . expression . dependencies : [ ] ;
44
50
this . scope . add ( this . index , dependencies ) ;
45
51
}
46
52
47
- // TODO more general approach to destructuring
48
- this . destructuredContexts = info . destructuredContexts || [ ] ;
49
- this . destructuredContexts . forEach ( name => {
50
- this . scope . add ( name , this . expression . dependencies ) ;
51
- } ) ;
52
-
53
53
this . children = mapChildren ( compiler , this , this . scope , info . children ) ;
54
54
55
55
this . else = info . else
@@ -76,31 +76,28 @@ export default class EachBlock extends Node {
76
76
name : this . compiler . getUniqueName ( 'create_each_block' ) ,
77
77
key : this . key ,
78
78
79
- indexNames : new Map ( block . indexNames ) ,
80
- listNames : new Map ( block . listNames )
79
+ bindings : new Map ( block . bindings )
81
80
} ) ;
82
81
83
- const listName = this . compiler . getUniqueName ( 'each_value' ) ;
82
+ this . each_block_value = this . compiler . getUniqueName ( 'each_value' ) ;
83
+
84
84
const indexName = this . index || this . compiler . getUniqueName ( `${ this . context } _index` ) ;
85
85
86
- this . block . indexNames . set ( this . context , indexName ) ;
87
- this . block . listNames . set ( this . context , listName ) ;
86
+ this . contexts . forEach ( prop => {
87
+ this . block . bindings . set ( prop . key . name , `ctx.${ this . each_block_value } [ctx.${ indexName } ]${ prop . tail } ` ) ;
88
+ } ) ;
88
89
89
90
if ( this . index ) {
90
91
this . block . getUniqueName ( this . index ) ; // this prevents name collisions (#1254)
91
92
}
92
93
93
- this . contextProps = [
94
- `${ listName } : list` ,
95
- `${ this . context } : list[i]` ,
96
- `${ indexName } : i`
97
- ] ;
94
+ this . contextProps = this . contexts . map ( prop => `${ prop . key . name } : list[i]${ prop . tail } ` ) ;
98
95
99
- if ( this . destructuredContexts ) {
100
- for ( let i = 0 ; i < this . destructuredContexts . length ; i += 1 ) {
101
- this . contextProps . push ( `${ this . destructuredContexts [ i ] } : list[i][ ${ i } ]` ) ;
102
- }
103
- }
96
+ // TODO only add these if necessary
97
+ this . contextProps . push (
98
+ `${ this . each_block_value } : list` ,
99
+ ` ${ indexName } : i`
100
+ ) ;
104
101
105
102
this . compiler . target . blocks . push ( this . block ) ;
106
103
this . initChildren ( this . block , stripWhitespace , nextSibling ) ;
@@ -135,7 +132,6 @@ export default class EachBlock extends Node {
135
132
const each = this . var ;
136
133
137
134
const create_each_block = this . block . name ;
138
- const each_block_value = this . block . listNames . get ( this . context ) ;
139
135
const iterations = this . iterations ;
140
136
141
137
const needsAnchor = this . next ? ! this . next . isDomNode ( ) : ! parentNode || ! this . parent . isDomNode ( ) ;
@@ -154,7 +150,6 @@ export default class EachBlock extends Node {
154
150
const vars = {
155
151
each,
156
152
create_each_block,
157
- each_block_value,
158
153
length,
159
154
iterations,
160
155
anchor,
@@ -163,7 +158,7 @@ export default class EachBlock extends Node {
163
158
164
159
const { snippet } = this . expression ;
165
160
166
- block . builders . init . addLine ( `var ${ each_block_value } = ${ snippet } ;` ) ;
161
+ block . builders . init . addLine ( `var ${ this . each_block_value } = ${ snippet } ;` ) ;
167
162
168
163
this . compiler . target . blocks . push ( deindent `
169
164
function ${ this . get_each_context } (ctx, list, i) {
@@ -195,7 +190,7 @@ export default class EachBlock extends Node {
195
190
196
191
// TODO neaten this up... will end up with an empty line in the block
197
192
block . builders . init . addBlock ( deindent `
198
- if (!${ each_block_value } .${ length } ) {
193
+ if (!${ this . each_block_value } .${ length } ) {
199
194
${ each_block_else } = ${ this . else . block . name } (#component, ctx);
200
195
${ each_block_else } .c();
201
196
}
@@ -211,9 +206,9 @@ export default class EachBlock extends Node {
211
206
212
207
if ( this . else . block . hasUpdateMethod ) {
213
208
block . builders . update . addBlock ( deindent `
214
- if (!${ each_block_value } .${ length } && ${ each_block_else } ) {
209
+ if (!${ this . each_block_value } .${ length } && ${ each_block_else } ) {
215
210
${ each_block_else } .p(changed, ctx);
216
- } else if (!${ each_block_value } .${ length } ) {
211
+ } else if (!${ this . each_block_value } .${ length } ) {
217
212
${ each_block_else } = ${ this . else . block . name } (#component, ctx);
218
213
${ each_block_else } .c();
219
214
${ each_block_else } .${ mountOrIntro } (${ initialMountNode } , ${ anchor } );
@@ -225,7 +220,7 @@ export default class EachBlock extends Node {
225
220
` ) ;
226
221
} else {
227
222
block . builders . update . addBlock ( deindent `
228
- if (${ each_block_value } .${ length } ) {
223
+ if (${ this . each_block_value } .${ length } ) {
229
224
if (${ each_block_else } ) {
230
225
${ each_block_else } .u();
231
226
${ each_block_else } .d();
@@ -267,7 +262,6 @@ export default class EachBlock extends Node {
267
262
{
268
263
each,
269
264
create_each_block,
270
- each_block_value,
271
265
length,
272
266
anchor,
273
267
mountOrIntro,
@@ -295,8 +289,8 @@ export default class EachBlock extends Node {
295
289
block . builders . init . addBlock ( deindent `
296
290
const ${ get_key } = ctx => ${ this . key . snippet } ;
297
291
298
- for (var #i = 0; #i < ${ each_block_value } .${ length } ; #i += 1) {
299
- let child_ctx = ${ this . get_each_context } (ctx, ${ each_block_value } , #i);
292
+ for (var #i = 0; #i < ${ this . each_block_value } .${ length } ; #i += 1) {
293
+ let child_ctx = ${ this . get_each_context } (ctx, ${ this . each_block_value } , #i);
300
294
let key = ${ get_key } (child_ctx);
301
295
${ blocks } [#i] = ${ lookup } [key] = ${ create_each_block } (#component, key, child_ctx);
302
296
}
@@ -323,9 +317,9 @@ export default class EachBlock extends Node {
323
317
const dynamic = this . block . hasUpdateMethod ;
324
318
325
319
block . builders . update . addBlock ( deindent `
326
- var ${ each_block_value } = ${ snippet } ;
320
+ var ${ this . each_block_value } = ${ snippet } ;
327
321
328
- ${ blocks } = @updateKeyedEach(${ blocks } , #component, changed, ${ get_key } , ${ dynamic ? '1' : '0' } , ctx, ${ each_block_value } , ${ lookup } , ${ updateMountNode } , ${ String ( this . block . hasOutroMethod ) } , ${ create_each_block } , "${ mountOrIntro } ", ${ anchor } , ${ this . get_each_context } );
322
+ ${ blocks } = @updateKeyedEach(${ blocks } , #component, changed, ${ get_key } , ${ dynamic ? '1' : '0' } , ctx, ${ this . each_block_value } , ${ lookup } , ${ updateMountNode } , ${ String ( this . block . hasOutroMethod ) } , ${ create_each_block } , "${ mountOrIntro } ", ${ anchor } , ${ this . get_each_context } );
329
323
` ) ;
330
324
331
325
if ( ! parentNode ) {
@@ -346,7 +340,6 @@ export default class EachBlock extends Node {
346
340
snippet : string ,
347
341
{
348
342
create_each_block,
349
- each_block_value,
350
343
length,
351
344
iterations,
352
345
anchor,
@@ -356,8 +349,8 @@ export default class EachBlock extends Node {
356
349
block . builders . init . addBlock ( deindent `
357
350
var ${ iterations } = [];
358
351
359
- for (var #i = 0; #i < ${ each_block_value } .${ length } ; #i += 1) {
360
- ${ iterations } [#i] = ${ create_each_block } (#component, ${ this . get_each_context } (ctx, ${ each_block_value } , #i));
352
+ for (var #i = 0; #i < ${ this . each_block_value } .${ length } ; #i += 1) {
353
+ ${ iterations } [#i] = ${ create_each_block } (#component, ${ this . get_each_context } (ctx, ${ this . each_block_value } , #i));
361
354
}
362
355
` ) ;
363
356
@@ -445,15 +438,15 @@ export default class EachBlock extends Node {
445
438
${ iterations } [#i].u();
446
439
${ iterations } [#i].d();
447
440
}
448
- ${ iterations } .length = ${ each_block_value } .${ length } ;
441
+ ${ iterations } .length = ${ this . each_block_value } .${ length } ;
449
442
` ;
450
443
451
444
block . builders . update . addBlock ( deindent `
452
445
if (${ condition } ) {
453
- ${ each_block_value } = ${ snippet } ;
446
+ ${ this . each_block_value } = ${ snippet } ;
454
447
455
- for (var #i = ${ start } ; #i < ${ each_block_value } .${ length } ; #i += 1) {
456
- const child_ctx = ${ this . get_each_context } (ctx, ${ each_block_value } , #i);
448
+ for (var #i = ${ start } ; #i < ${ this . each_block_value } .${ length } ; #i += 1) {
449
+ const child_ctx = ${ this . get_each_context } (ctx, ${ this . each_block_value } , #i);
457
450
458
451
${ forLoopBody }
459
452
}
@@ -481,8 +474,7 @@ export default class EachBlock extends Node {
481
474
const { compiler } = this ;
482
475
const { snippet } = this . expression ;
483
476
484
- const props = [ `${ this . context } : item` ]
485
- . concat ( this . destructuredContexts . map ( ( name , i ) => `${ name } : item[${ i } ]` ) ) ;
477
+ const props = this . contexts . map ( prop => `${ prop . key . name } : item${ prop . tail } ` ) ;
486
478
487
479
const getContext = this . index
488
480
? `(item, i) => Object.assign({}, ctx, { ${ props . join ( ', ' ) } , ${ this . index } : i })`
0 commit comments