@@ -28,12 +28,15 @@ interface ComputedWatchInfo {
28
28
computedUpdaters : Array < ( ...args : unknown [ ] ) => boolean >
29
29
computedRelatedPathValues : Array < Array < dataTracer . RelatedPathValue > >
30
30
watchCurVal : Array < unknown >
31
- _triggerFromComputedAttached : Record < string , boolean >
31
+ watchDisabled : boolean
32
32
}
33
33
34
34
enum ComputedWatchInitStatus {
35
35
CREATED ,
36
36
ATTACHED ,
37
+ DISABLE_WATCHES ,
38
+ ENABLE_WATCHES ,
39
+ CALL_WATCHES ,
37
40
}
38
41
39
42
let computedWatchDefIdInc = 0
@@ -53,22 +56,24 @@ class ComputedBuilder {
53
56
private computedWatchDefId = computedWatchDefIdInc ++
54
57
private computedList : Array < [ string , ( data : Record < string , unknown > ) => unknown ] > = [ ]
55
58
private watchList : Array < DataPathWithOptions [ ] > = [ ]
59
+ private watchFunctions : Array < ( ...args : any [ ] ) => void > = [ ]
56
60
57
61
constructor ( ) {
58
62
const computedWatchDefId = this . computedWatchDefId
59
63
const computedList = this . computedList
60
64
const watchList = this . watchList
65
+ const watchFunctions = this . watchFunctions
61
66
this . observersItems . push ( {
62
67
fields : '_computedWatchInit' ,
63
68
observer ( this : BehaviorExtend ) {
64
69
const status = this . data . _computedWatchInit
65
70
if ( status === ComputedWatchInitStatus . CREATED ) {
66
71
// init data fields
67
- const computedWatchInfo = {
72
+ const computedWatchInfo : ComputedWatchInfo = {
68
73
computedUpdaters : [ ] ,
69
74
computedRelatedPathValues : new Array ( computedList . length ) ,
70
75
watchCurVal : new Array ( watchList . length ) ,
71
- _triggerFromComputedAttached : Object . create ( null ) ,
76
+ watchDisabled : false ,
72
77
}
73
78
if ( ! this . _computedWatchInfo ) this . _computedWatchInfo = { }
74
79
this . _computedWatchInfo [ computedWatchDefId ] = computedWatchInfo
@@ -95,7 +100,6 @@ class ComputedBuilder {
95
100
this . setData ( {
96
101
[ targetField ] : dataTracer . unwrap ( val ) ,
97
102
} )
98
- computedWatchInfo . _triggerFromComputedAttached [ targetField ] = true
99
103
computedWatchInfo . computedRelatedPathValues [ index ] = relatedPathValuesOnDef
100
104
101
105
// will be invoked when setData is called
@@ -140,6 +144,14 @@ class ComputedBuilder {
140
144
}
141
145
computedWatchInfo . computedUpdaters . push ( updateValueAndRelatedPaths )
142
146
} )
147
+ } else if ( status === ComputedWatchInitStatus . DISABLE_WATCHES ) {
148
+ const computedWatchInfo = this . _computedWatchInfo [ computedWatchDefId ]
149
+ computedWatchInfo . watchDisabled = true
150
+ } else if ( status === ComputedWatchInitStatus . ENABLE_WATCHES ) {
151
+ const computedWatchInfo = this . _computedWatchInfo [ computedWatchDefId ]
152
+ computedWatchInfo . watchDisabled = false
153
+ } else if ( status === ComputedWatchInitStatus . CALL_WATCHES ) {
154
+ watchFunctions . forEach ( ( func ) => func . call ( this ) )
143
155
}
144
156
} ,
145
157
} )
@@ -170,32 +182,20 @@ class ComputedBuilder {
170
182
}
171
183
172
184
addWatch ( watchPath : string , listener : ( args : any ) => void ) {
185
+ const computedWatchDefId = this . computedWatchDefId
173
186
const paths = dataPath . parseMultiDataPaths ( watchPath )
174
187
const index = this . watchList . length
175
188
this . watchList . push ( paths )
176
- const computedWatchDefId = this . computedWatchDefId
189
+ this . watchFunctions . push ( function ( this : BehaviorExtend ) {
190
+ const args = paths . map ( ( { path } ) => dataPath . getDataOnPath ( this . data , path ) )
191
+ listener . apply ( this , args )
192
+ } )
177
193
this . observersItems . push ( {
178
194
fields : watchPath ,
179
195
observer ( this : BehaviorExtend ) {
180
196
if ( ! this . _computedWatchInfo ) return
181
197
const computedWatchInfo = this . _computedWatchInfo [ computedWatchDefId ]
182
198
if ( ! computedWatchInfo ) return
183
- // (issue #58) ignore watch func when trigger by computed attached
184
- if ( Object . keys ( computedWatchInfo . _triggerFromComputedAttached ) . length ) {
185
- const pathsMap : Record < string , boolean > = { }
186
- paths . forEach ( ( path ) => ( pathsMap [ path . path [ 0 ] ] = true ) )
187
- for ( const computedVal in computedWatchInfo . _triggerFromComputedAttached ) {
188
- if ( computedWatchInfo . _triggerFromComputedAttached [ computedVal ] ) {
189
- if (
190
- pathsMap [ computedVal ] &&
191
- computedWatchInfo . _triggerFromComputedAttached [ computedVal ]
192
- ) {
193
- computedWatchInfo . _triggerFromComputedAttached [ computedVal ] = false
194
- return
195
- }
196
- }
197
- }
198
- }
199
199
const oldVal = computedWatchInfo . watchCurVal [ index ]
200
200
201
201
// get new watching field value
@@ -207,6 +207,7 @@ class ComputedBuilder {
207
207
options . deepCmp ? deepClone ( val ) : val ,
208
208
)
209
209
computedWatchInfo . watchCurVal [ index ] = curVal
210
+ if ( computedWatchInfo . watchDisabled ) return
210
211
211
212
// compare
212
213
let changed = false
@@ -245,6 +246,29 @@ export const behavior = Behavior({
245
246
} ,
246
247
} ,
247
248
249
+ methods : {
250
+ disableWatches ( ) {
251
+ this . setData ( {
252
+ _computedWatchInit : ComputedWatchInitStatus . DISABLE_WATCHES ,
253
+ } )
254
+ } ,
255
+ enableWatches ( callWatchesImmediately : boolean ) {
256
+ this . setData ( {
257
+ _computedWatchInit : ComputedWatchInitStatus . ENABLE_WATCHES ,
258
+ } )
259
+ if ( callWatchesImmediately ) {
260
+ this . setData ( {
261
+ _computedWatchInit : ComputedWatchInitStatus . CALL_WATCHES ,
262
+ } )
263
+ }
264
+ } ,
265
+ triggerAllWatches ( ) {
266
+ this . setData ( {
267
+ _computedWatchInit : ComputedWatchInitStatus . CALL_WATCHES ,
268
+ } )
269
+ } ,
270
+ } ,
271
+
248
272
definitionFilter ( defFields : any & BehaviorExtend ) {
249
273
const computedDef = defFields . computed
250
274
const watchDef = defFields . watch
@@ -473,6 +497,29 @@ export function computed<
473
497
return ctx . data as any
474
498
}
475
499
500
+ export const generateWatches = ( self : BehaviorExtend ) => ( {
501
+ disableWatches ( ) {
502
+ self . setData ( {
503
+ _computedWatchInit : ComputedWatchInitStatus . DISABLE_WATCHES ,
504
+ } )
505
+ } ,
506
+ enableWatches ( triggerWatchesImmediately : boolean ) {
507
+ self . setData ( {
508
+ _computedWatchInit : ComputedWatchInitStatus . ENABLE_WATCHES ,
509
+ } )
510
+ if ( triggerWatchesImmediately ) {
511
+ self . setData ( {
512
+ _computedWatchInit : ComputedWatchInitStatus . CALL_WATCHES ,
513
+ } )
514
+ }
515
+ } ,
516
+ triggerAllWatches ( ) {
517
+ self . setData ( {
518
+ _computedWatchInit : ComputedWatchInitStatus . CALL_WATCHES ,
519
+ } )
520
+ } ,
521
+ } )
522
+
476
523
export const watch = (
477
524
ctx : adapter . builder . BuilderContext < any , any , any > ,
478
525
watchPath : string ,
@@ -484,4 +531,5 @@ export const watch = (
484
531
builder . observersItems . forEach ( ( { fields, observer } ) => {
485
532
ctx . observer ( fields as any , observer )
486
533
} )
534
+ return generateWatches ( ctx . self )
487
535
}
0 commit comments