@@ -23,7 +23,7 @@ export type PropertyType = WechatMiniprogram.Component.AllProperty
23
23
export type PropertyToData < T extends PropertyType > = WechatMiniprogram . Component . PropertyToData < T >
24
24
type IAnyObject = WechatMiniprogram . IAnyObject
25
25
26
- type NewFieldList < TObject , TNewObject > =
26
+ export type NewFieldList < TObject , TNewObject > =
27
27
Extract < keyof TObject , keyof TNewObject > extends never ? TNewObject : never
28
28
29
29
type Lifetimes = {
@@ -47,7 +47,12 @@ export type Component<
47
47
TProperty extends PropertyList ,
48
48
TMethod extends MethodList ,
49
49
TExtraThisFields extends DataList = Empty ,
50
- > = WechatMiniprogram . Component . Instance < TData , TProperty , TMethod , [ ] > & TExtraThisFields
50
+ > = WechatMiniprogram . Component . Instance < TData , TProperty , TMethod , [ ] , Empty > &
51
+ TExtraThisFields & {
52
+ traitBehavior : < TOut extends { [ x : string ] : any } > (
53
+ traitBehavior : TraitBehavior < any , TOut > ,
54
+ ) => TOut | undefined
55
+ }
51
56
52
57
export type ComponentMethod = ( ...any : [ ] ) => void
53
58
@@ -103,11 +108,18 @@ class ChainingPolyfillMetadata {
103
108
}
104
109
this . traitGroup . implement ( trait_behavior , impl )
105
110
} ,
106
- observer : ( ) => {
111
+ observer : ( paths : any , func : ( newValue : any ) => void ) => {
107
112
if ( this . initDone ) {
108
113
throw new Error ( 'Cannot execute init-time functions after initialization' )
109
114
}
110
- // TODO
115
+ const fields = typeof paths === 'string' ? paths : paths . join ( ', ' )
116
+ const funcs = this . observers [ fields ]
117
+ if ( ! funcs ) {
118
+ throw new Error (
119
+ 'The `observer` call should has a corresponding `.observer` call in chaining' ,
120
+ )
121
+ }
122
+ funcs . add ( func )
111
123
} ,
112
124
lifetime : ( name : string , func : ( ) => void ) => {
113
125
if ( this . initDone ) {
@@ -142,12 +154,14 @@ class ChainingPolyfillMetadata {
142
154
}
143
155
144
156
callLifetime ( caller : unknown , name : string , ...args : any [ ] ) {
145
- const funcs = getChainingPolyfillMetadata ( self ) . lifetimes [ name ] ?? [ ]
157
+ const funcs = this . lifetimes [ name ]
158
+ if ( ! funcs ) return
146
159
funcs . call ( caller , args )
147
160
}
148
161
149
162
callPageLifetime ( caller : unknown , name : string , ...args : any [ ] ) {
150
- const funcs = getChainingPolyfillMetadata ( self ) . pageLifetimes [ name ] ?? [ ]
163
+ const funcs = this . pageLifetimes [ name ]
164
+ if ( ! funcs ) return
151
165
funcs . call ( caller , args )
152
166
}
153
167
}
@@ -156,47 +170,56 @@ const getChainingPolyfillMetadata = (comp: GeneralComponent): ChainingPolyfillMe
156
170
return comp . _$chainingPolyfill
157
171
}
158
172
173
+ const takeChainingPolyfillInitData = (
174
+ comp : GeneralComponent ,
175
+ ) : ChainingPolyfillInitData | undefined => {
176
+ const id = comp . data . _$chainingPolyfillId
177
+ if ( ! ( id >= 0 ) ) return undefined
178
+ comp . data . _$chainingPolyfillId = - 1
179
+ const initData = initDataMap [ id ]
180
+ const cloneMap = ( src : { [ k : string ] : FuncArr < any > } ) => {
181
+ const dest = { } as typeof src
182
+ const keys = Object . keys ( src )
183
+ for ( let i = 0 ; i < keys . length ; i += 1 ) {
184
+ const key = keys [ i ] !
185
+ dest [ key ] = src [ key ] . clone ( )
186
+ }
187
+ return dest
188
+ }
189
+ return {
190
+ lifetimes : cloneMap ( initData . lifetimes ) ,
191
+ pageLifetimes : cloneMap ( initData . lifetimes ) ,
192
+ observers : cloneMap ( initData . observers ) ,
193
+ initFuncs : initData . initFuncs . clone ( ) ,
194
+ }
195
+ }
196
+
159
197
const chainingPolyfillBehavior = Behavior ( {
160
198
lifetimes : {
161
199
created ( ) {
162
200
const self = this as any
163
- if ( self . data . _$chainingPolyfillMetadata ) {
164
- const initData = self . data . _$chainingPolyfillMetadata as ChainingPolyfillInitData
165
- self . data . _$chainingPolyfillMetadata = null
201
+ const initData = takeChainingPolyfillInitData ( self )
202
+ if ( initData ) {
166
203
const chainingPolyfillMetadata = new ChainingPolyfillMetadata ( initData )
167
204
self . _$chainingPolyfill = chainingPolyfillMetadata
168
205
const ctx = chainingPolyfillMetadata . generateBuilderContext ( self )
169
206
initData . initFuncs . call ( self , [ ctx , chainingPolyfillMetadata ] )
170
207
chainingPolyfillMetadata . setInitDone ( )
171
208
}
172
- getChainingPolyfillMetadata ( this ) . callLifetime ( this , 'created' )
173
- } ,
174
- attached ( ) {
175
- getChainingPolyfillMetadata ( this ) . callLifetime ( this , 'attached' )
176
- } ,
177
- moved ( ) {
178
- getChainingPolyfillMetadata ( this ) . callLifetime ( this , 'moved' )
179
- } ,
180
- detached ( ) {
181
- getChainingPolyfillMetadata ( this ) . callLifetime ( this , 'detached' )
182
- } ,
183
- ready ( ) {
184
- getChainingPolyfillMetadata ( this ) . callLifetime ( this , 'ready' )
185
209
} ,
186
210
} ,
187
- pageLifetimes : {
188
- show ( ) {
189
- getChainingPolyfillMetadata ( this ) . callPageLifetime ( this , 'show' )
190
- } ,
191
- hide ( ) {
192
- getChainingPolyfillMetadata ( this ) . callPageLifetime ( this , 'hide' )
193
- } ,
194
- resize ( size ) {
195
- getChainingPolyfillMetadata ( this ) . callPageLifetime ( this , 'resize' , size )
211
+ methods : {
212
+ traitBehavior < TOut extends { [ x : string ] : any } > (
213
+ traitBehavior : TraitBehavior < any , TOut > ,
214
+ ) : TOut | undefined {
215
+ return getChainingPolyfillMetadata ( this ) . traitGroup . get ( traitBehavior )
196
216
} ,
197
217
} ,
198
218
} )
199
219
220
+ let behaviorIdInc = 1
221
+ const initDataMap : { [ id : number ] : ChainingPolyfillInitData } = { }
222
+
200
223
export class BaseBehaviorBuilder <
201
224
TPrevData extends DataList = Empty ,
202
225
TData extends DataList = Empty ,
@@ -207,26 +230,58 @@ export class BaseBehaviorBuilder<
207
230
TComponentExport = never ,
208
231
TExtraThisFields extends DataList = Empty ,
209
232
> {
233
+ behaviorId : number
234
+ private _$initData = {
235
+ lifetimes : { } ,
236
+ pageLifetimes : { } ,
237
+ observers : { } ,
238
+ initFuncs : new FuncArr ( ) ,
239
+ } as ChainingPolyfillInitData
210
240
protected _$definition = {
211
- data : {
212
- _$chainingPolyfillMetadata : {
213
- lifetimes : { } ,
214
- observers : { } ,
215
- } as ChainingPolyfillInitData ,
216
- } as DataList ,
241
+ data : { } as DataList ,
217
242
properties : { } as WechatMiniprogram . Behavior . PropertyOption ,
218
243
methods : { } as MethodList ,
219
244
behaviors : [ chainingPolyfillBehavior ] ,
220
- lifetimes : { } as { [ key : string ] : GeneralFuncType } ,
221
- pageLifetimes : { } as { [ key : string ] : GeneralFuncType } ,
245
+ lifetimes : {
246
+ created ( ) {
247
+ getChainingPolyfillMetadata ( this ) . callLifetime ( this , 'created' )
248
+ } ,
249
+ attached ( ) {
250
+ getChainingPolyfillMetadata ( this ) . callLifetime ( this , 'attached' )
251
+ } ,
252
+ moved ( ) {
253
+ getChainingPolyfillMetadata ( this ) . callLifetime ( this , 'moved' )
254
+ } ,
255
+ detached ( ) {
256
+ getChainingPolyfillMetadata ( this ) . callLifetime ( this , 'detached' )
257
+ } ,
258
+ ready ( ) {
259
+ getChainingPolyfillMetadata ( this ) . callLifetime ( this , 'ready' )
260
+ } ,
261
+ } ,
262
+ pageLifetimes : {
263
+ show ( ) {
264
+ getChainingPolyfillMetadata ( this ) . callPageLifetime ( this , 'show' )
265
+ } ,
266
+ hide ( ) {
267
+ getChainingPolyfillMetadata ( this ) . callPageLifetime ( this , 'hide' )
268
+ } ,
269
+ resize ( size : unknown ) {
270
+ getChainingPolyfillMetadata ( this ) . callPageLifetime ( this , 'resize' , size )
271
+ } ,
272
+ } ,
222
273
observers : [ ] as { fields : string ; observer : GeneralFuncType } [ ] ,
223
274
relations : { } as { [ key : string ] : WechatMiniprogram . Component . RelationOption } ,
224
275
externalClasses : [ ] as string [ ] ,
225
276
export : undefined as undefined | ( ( ) => TComponentExport ) ,
277
+ options : undefined as undefined | WechatMiniprogram . Component . ComponentOptions ,
226
278
}
227
279
228
- protected _$getChainingPolyfillInitData ( ) : ChainingPolyfillInitData {
229
- return this . _$definition . data . chainingPolyfillMetadata
280
+ constructor ( ) {
281
+ this . behaviorId = behaviorIdInc
282
+ behaviorIdInc += 1
283
+ this . _$definition . data . _$chainingPolyfillId = this . behaviorId
284
+ initDataMap [ this . behaviorId ] = this . _$initData
230
285
}
231
286
232
287
/** Add external classes */
@@ -344,7 +399,17 @@ export class BaseBehaviorBuilder<
344
399
func : ( this : Component < TData , TProperty , TMethod , TExtraThisFields > , ...args : any [ ] ) => any ,
345
400
) : ResolveBehaviorBuilder < this> {
346
401
const fields = typeof paths === 'string' ? paths : paths . join ( ', ' )
347
- this . _$definition . observers . push ( { fields, observer : func } )
402
+ const assistObservers = new FuncArr ( )
403
+ assistObservers . add ( func )
404
+ const observer = function (
405
+ this : Component < TData , TProperty , TMethod , TExtraThisFields > ,
406
+ ...args : any [ ]
407
+ ) {
408
+ assistObservers . call ( this , args )
409
+ }
410
+ this . _$definition . observers . push ( { fields, observer } )
411
+ const observers = this . _$initData . observers
412
+ observers [ fields ] = assistObservers
348
413
return this as any
349
414
}
350
415
@@ -358,7 +423,7 @@ export class BaseBehaviorBuilder<
358
423
...args : Parameters < Lifetimes [ L ] >
359
424
) => ReturnType < Lifetimes [ L ] > ,
360
425
) : ResolveBehaviorBuilder < this> {
361
- const lifetimes = this . _$getChainingPolyfillInitData ( ) . lifetimes
426
+ const lifetimes = this . _$initData . lifetimes
362
427
if ( ! lifetimes [ name ] ) {
363
428
lifetimes [ name ] = new FuncArr ( )
364
429
}
@@ -376,7 +441,7 @@ export class BaseBehaviorBuilder<
376
441
...args : Parameters < PageLifetimes [ L ] >
377
442
) => any ,
378
443
) : ResolveBehaviorBuilder < this> {
379
- const pageLifetimes = this . _$getChainingPolyfillInitData ( ) . pageLifetimes
444
+ const pageLifetimes = this . _$initData . pageLifetimes
380
445
if ( ! pageLifetimes [ name ] ) {
381
446
pageLifetimes [ name ] = new FuncArr ( )
382
447
}
@@ -422,7 +487,7 @@ export class BaseBehaviorBuilder<
422
487
TExtraThisFields
423
488
>
424
489
> {
425
- this . _$getChainingPolyfillInitData ( ) . initFuncs . add ( ( ctx , meta : ChainingPolyfillMetadata ) => {
490
+ this . _$initData . initFuncs . add ( ( ctx , meta : ChainingPolyfillMetadata ) => {
426
491
const comp = ctx . self
427
492
const exported = func . call ( comp , ctx )
428
493
meta . handleBuilderContextExport ( comp , exported )
@@ -436,7 +501,7 @@ export class BaseBehaviorBuilder<
436
501
TNewMethod extends MethodList = Empty ,
437
502
TNewComponentExport = never ,
438
503
> (
439
- definition : WechatMiniprogram . Component . Options < TNewData , TNewProperty , TNewMethod , any > &
504
+ definition : ClassicDefinition < TNewData , TNewProperty , TNewMethod > &
440
505
ThisType <
441
506
Component <
442
507
TData & TNewData ,
@@ -475,7 +540,7 @@ export class BaseBehaviorBuilder<
475
540
export : exports ,
476
541
} = definition
477
542
if ( behaviors ) {
478
- this . _$definition . behaviors . push ( ...behaviors )
543
+ this . _$definition . behaviors . push ( ...( behaviors as any [ ] ) )
479
544
}
480
545
if ( rawProperties ) {
481
546
Object . assign ( this . _$definition . properties , rawProperties )
@@ -567,3 +632,14 @@ export interface BuilderContext<
567
632
type EventListener < TDetail extends IAnyObject > = ( ev : Event < TDetail > ) => boolean | void
568
633
569
634
type Event < TDetail extends IAnyObject > = WechatMiniprogram . CustomEvent < TDetail , any , any , any >
635
+
636
+ export type ClassicDefinition <
637
+ TData extends WechatMiniprogram . Component . DataOption ,
638
+ TProperty extends WechatMiniprogram . Component . PropertyOption ,
639
+ TMethod extends WechatMiniprogram . Component . MethodOption ,
640
+ > = Optional < WechatMiniprogram . Component . Data < TData > > &
641
+ Optional < WechatMiniprogram . Component . Property < TProperty > > &
642
+ Optional < WechatMiniprogram . Component . Method < TMethod > > &
643
+ Optional < WechatMiniprogram . Component . Behavior < WechatMiniprogram . Component . BehaviorOption > > &
644
+ Optional < WechatMiniprogram . Component . Lifetimes > &
645
+ Partial < WechatMiniprogram . Component . OtherOption >
0 commit comments