@@ -28,12 +28,15 @@ interface ComputedWatchInfo {
2828 computedUpdaters : Array < ( ...args : unknown [ ] ) => boolean >
2929 computedRelatedPathValues : Array < Array < dataTracer . RelatedPathValue > >
3030 watchCurVal : Array < unknown >
31- _triggerFromComputedAttached : Record < string , boolean >
31+ watchDisabled : boolean
3232}
3333
3434enum ComputedWatchInitStatus {
3535 CREATED ,
3636 ATTACHED ,
37+ DISABLE_WATCHES ,
38+ ENABLE_WATCHES ,
39+ CALL_WATCHES ,
3740}
3841
3942let computedWatchDefIdInc = 0
@@ -53,22 +56,24 @@ class ComputedBuilder {
5356 private computedWatchDefId = computedWatchDefIdInc ++
5457 private computedList : Array < [ string , ( data : Record < string , unknown > ) => unknown ] > = [ ]
5558 private watchList : Array < DataPathWithOptions [ ] > = [ ]
59+ private watchFunctions : Array < ( ...args : any [ ] ) => void > = [ ]
5660
5761 constructor ( ) {
5862 const computedWatchDefId = this . computedWatchDefId
5963 const computedList = this . computedList
6064 const watchList = this . watchList
65+ const watchFunctions = this . watchFunctions
6166 this . observersItems . push ( {
6267 fields : '_computedWatchInit' ,
6368 observer ( this : BehaviorExtend ) {
6469 const status = this . data . _computedWatchInit
6570 if ( status === ComputedWatchInitStatus . CREATED ) {
6671 // init data fields
67- const computedWatchInfo = {
72+ const computedWatchInfo : ComputedWatchInfo = {
6873 computedUpdaters : [ ] ,
6974 computedRelatedPathValues : new Array ( computedList . length ) ,
7075 watchCurVal : new Array ( watchList . length ) ,
71- _triggerFromComputedAttached : Object . create ( null ) ,
76+ watchDisabled : false ,
7277 }
7378 if ( ! this . _computedWatchInfo ) this . _computedWatchInfo = { }
7479 this . _computedWatchInfo [ computedWatchDefId ] = computedWatchInfo
@@ -95,7 +100,6 @@ class ComputedBuilder {
95100 this . setData ( {
96101 [ targetField ] : dataTracer . unwrap ( val ) ,
97102 } )
98- computedWatchInfo . _triggerFromComputedAttached [ targetField ] = true
99103 computedWatchInfo . computedRelatedPathValues [ index ] = relatedPathValuesOnDef
100104
101105 // will be invoked when setData is called
@@ -140,6 +144,14 @@ class ComputedBuilder {
140144 }
141145 computedWatchInfo . computedUpdaters . push ( updateValueAndRelatedPaths )
142146 } )
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 ) )
143155 }
144156 } ,
145157 } )
@@ -170,32 +182,20 @@ class ComputedBuilder {
170182 }
171183
172184 addWatch ( watchPath : string , listener : ( args : any ) => void ) {
185+ const computedWatchDefId = this . computedWatchDefId
173186 const paths = dataPath . parseMultiDataPaths ( watchPath )
174187 const index = this . watchList . length
175188 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+ } )
177193 this . observersItems . push ( {
178194 fields : watchPath ,
179195 observer ( this : BehaviorExtend ) {
180196 if ( ! this . _computedWatchInfo ) return
181197 const computedWatchInfo = this . _computedWatchInfo [ computedWatchDefId ]
182198 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- }
199199 const oldVal = computedWatchInfo . watchCurVal [ index ]
200200
201201 // get new watching field value
@@ -207,6 +207,7 @@ class ComputedBuilder {
207207 options . deepCmp ? deepClone ( val ) : val ,
208208 )
209209 computedWatchInfo . watchCurVal [ index ] = curVal
210+ if ( computedWatchInfo . watchDisabled ) return
210211
211212 // compare
212213 let changed = false
@@ -245,6 +246,29 @@ export const behavior = Behavior({
245246 } ,
246247 } ,
247248
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+
248272 definitionFilter ( defFields : any & BehaviorExtend ) {
249273 const computedDef = defFields . computed
250274 const watchDef = defFields . watch
@@ -473,6 +497,29 @@ export function computed<
473497 return ctx . data as any
474498}
475499
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+
476523export const watch = (
477524 ctx : adapter . builder . BuilderContext < any , any , any > ,
478525 watchPath : string ,
@@ -484,4 +531,5 @@ export const watch = (
484531 builder . observersItems . forEach ( ( { fields, observer } ) => {
485532 ctx . observer ( fields as any , observer )
486533 } )
534+ return generateWatches ( ctx . self )
487535}
0 commit comments