@@ -7,7 +7,7 @@ angular.module('angular-meteor.reactive', ['angular-meteor.reactive-scope']).fac
7
7
8
8
this . context = context ;
9
9
10
- if ( ( this . context . constructor || angular . noop ) . toString ( ) . indexOf ( 'Scope' ) > - 1 ) {
10
+ if ( this . _isScope ( this . context ) ) {
11
11
this . scope = this . context ;
12
12
}
13
13
@@ -16,19 +16,24 @@ angular.module('angular-meteor.reactive', ['angular-meteor.reactive-scope']).fac
16
16
}
17
17
18
18
attach ( scope ) {
19
- if ( ! this . scope && ( scope . constructor || angular . noop ) . toString ( ) . indexOf ( 'Scope' ) > - 1 ) {
19
+ if ( ! this . scope && this . _isScope ( scope ) ) {
20
20
this . scope = scope ;
21
21
}
22
22
23
23
return this ;
24
24
}
25
25
26
+ _isScope ( obj ) {
27
+ return obj instanceof Object . getPrototypeOf ( $rootScope ) . constructor ;
28
+ }
29
+
26
30
_handleCursor ( cursor , name ) {
27
31
if ( angular . isUndefined ( this . context [ name ] ) ) {
28
- this . _declareReactiveProperty ( name , cursor . fetch ( ) ) ;
32
+ this . _setValHelper ( name , cursor . fetch ( ) ) ;
29
33
}
30
34
else {
31
- jsondiffpatch . patch ( this . context [ name ] , jsondiffpatch . diff ( this . context [ name ] , cursor . fetch ( ) ) ) ;
35
+ let diff = jsondiffpatch . diff ( this . context [ name ] , cursor . fetch ( ) ) ;
36
+ jsondiffpatch . patch ( this . context [ name ] , diff ) ;
32
37
}
33
38
34
39
let initial = true ;
@@ -40,7 +45,8 @@ angular.module('angular-meteor.reactive', ['angular-meteor.reactive-scope']).fac
40
45
}
41
46
} ,
42
47
changedAt : ( doc , oldDoc , atIndex ) => {
43
- jsondiffpatch . patch ( this . context [ name ] [ atIndex ] , jsondiffpatch . diff ( this . context [ name ] [ atIndex ] , doc ) ) ;
48
+ let diff = jsondiffpatch . diff ( this . context [ name ] [ atIndex ] , doc ) ;
49
+ jsondiffpatch . patch ( this . context [ name ] [ atIndex ] , diff ) ;
44
50
this . _propertyChanged ( name ) ;
45
51
} ,
46
52
movedTo : ( doc , fromIndex , toIndex ) => {
@@ -60,95 +66,84 @@ angular.module('angular-meteor.reactive', ['angular-meteor.reactive-scope']).fac
60
66
61
67
_handleNonCursor ( data , name ) {
62
68
if ( angular . isUndefined ( this . context [ name ] ) ) {
63
- this . _declareReactiveProperty ( name , data ) ;
69
+ this . _setValHelper ( name , data ) ;
64
70
}
65
71
else {
66
72
if ( ( ! _ . isObject ( data ) && ! _ . isArray ( data ) ) ||
67
73
( ! _ . isObject ( this . context [ name ] ) && ! _ . isArray ( this . context [ name ] ) ) ) {
68
74
this . context [ name ] = data ;
69
75
}
70
76
else {
71
- jsondiffpatch . patch ( this . context [ name ] , jsondiffpatch . diff ( this . context [ name ] , data ) ) ;
77
+ let diff = jsondiffpatch . diff ( this . context [ name ] , data )
78
+ jsondiffpatch . patch ( this . context [ name ] , diff ) ;
72
79
this . _propertyChanged ( name ) ;
73
80
}
74
81
}
75
82
}
76
83
77
- static _isMeteorCursor ( obj ) {
78
- return obj instanceof Mongo . Collection . Cursor ;
79
- } ;
80
-
81
84
helpers ( props ) {
82
- _ . chain ( props ) . map ( ( propValue , propName ) => {
83
- return {
84
- key : propName ,
85
- value : propValue
86
- }
87
- } ) . sortBy ( ( prop , index , arr ) => {
88
- if ( angular . isFunction ( prop . value ) ) {
89
- return arr . length + index ;
90
- }
91
- else {
92
- return index ;
93
- }
94
- } ) . forEach ( ( prop ) => {
95
- if ( ! angular . isFunction ( prop . value ) ) {
96
- this . _declareReactiveProperty ( prop . key , prop . value ) ;
97
- }
98
- else {
99
- this . stoppables . push ( Tracker . autorun ( ( comp ) => {
100
- let data = prop . value . apply ( this . context ) ;
101
-
102
- Tracker . nonreactive ( ( ) => {
103
- if ( ReactiveContext . _isMeteorCursor ( data ) ) {
104
- let stoppableObservation = this . _handleCursor ( data , prop . key ) ;
105
-
106
- comp . onInvalidate ( ( ) => {
107
- stoppableObservation . stop ( ) ;
108
- while ( this . context [ prop . key ] . length > 0 ) {
109
- this . context [ prop . key ] . pop ( ) ;
110
- }
111
- } ) ;
112
- }
113
- else {
114
- this . _handleNonCursor ( data , prop . key ) ;
115
- }
116
-
117
- this . _propertyChanged ( prop . key ) ;
118
- } ) ;
119
- } ) ) ;
120
- }
85
+ _ . each ( props , ( v , k ) => {
86
+ if ( _ . isFunction ( v ) )
87
+ this . _setFnHelper ( k , v ) ;
88
+ else
89
+ this . _setValHelper ( k , v ) ;
121
90
} ) ;
122
91
123
92
return this ;
124
93
}
125
94
126
- _declareReactiveProperty ( name , initialValue ) {
127
- this . propertiesTrackerDeps [ name ] = new Tracker . Dependency ( ) ;
128
- let property = initialValue ;
129
- let self = this ;
95
+ _setValHelper ( k , v ) {
96
+ this . propertiesTrackerDeps [ k ] = new Tracker . Dependency ( ) ;
97
+ v = _ . clone ( v ) ;
130
98
131
- Object . defineProperty ( this . context , name , {
99
+ Object . defineProperty ( this . context , k , {
132
100
configurable : true ,
133
101
enumerable : true ,
134
102
135
- get : function ( ) {
136
- self . propertiesTrackerDeps [ name ] . depend ( ) ;
137
- return property ;
103
+ get : ( ) => {
104
+ this . propertiesTrackerDeps [ k ] . depend ( ) ;
105
+ return v ;
138
106
} ,
139
- set : function ( newValue ) {
140
- property = newValue ;
141
- self . propertiesTrackerDeps [ name ] . changed ( ) ;
107
+ set : ( newValue ) => {
108
+ v = newValue ;
109
+ this . propertiesTrackerDeps [ k ] . changed ( ) ;
142
110
}
143
111
} ) ;
144
112
}
145
113
146
- _propertyChanged ( propName ) {
114
+ _setFnHelper ( k , fn ) {
115
+ this . stoppables . push ( Tracker . autorun ( ( comp ) => {
116
+ let data = fn . apply ( this . context ) ;
117
+
118
+ Tracker . nonreactive ( ( ) => {
119
+ if ( this . _isMeteorCursor ( data ) ) {
120
+ let stoppableObservation = this . _handleCursor ( data , k ) ;
121
+
122
+ comp . onInvalidate ( ( ) => {
123
+ stoppableObservation . stop ( ) ;
124
+ // empty set once cursor is invalidated
125
+ this . context [ k ] . splice ( 0 ) ;
126
+ } ) ;
127
+ }
128
+ else {
129
+ this . _handleNonCursor ( data , k ) ;
130
+ }
131
+
132
+ this . _propertyChanged ( k ) ;
133
+ } ) ;
134
+ } ) ) ;
135
+ }
136
+
137
+ _isMeteorCursor ( obj ) {
138
+ return obj instanceof Mongo . Collection . Cursor ;
139
+ }
140
+
141
+ _propertyChanged ( k ) {
147
142
if ( this . scope && ! $rootScope . $$phase ) {
148
143
this . scope . $digest ( ) ;
149
144
}
150
145
151
- this . propertiesTrackerDeps [ propName ] . changed ( ) ;
146
+ this . propertiesTrackerDeps [ k ] . changed ( ) ;
152
147
}
153
148
154
149
subscribe ( name , fn ) {
@@ -159,7 +154,8 @@ angular.module('angular-meteor.reactive', ['angular-meteor.reactive-scope']).fac
159
154
}
160
155
else {
161
156
this . autorun ( ( ) => {
162
- this . stoppables . push ( Meteor . subscribe ( name , ...( fn ( ) || [ ] ) ) ) ;
157
+ let args = fn ( ) || [ ] ;
158
+ this . stoppables . push ( Meteor . subscribe ( name , ...args ) ) ;
163
159
} ) ;
164
160
}
165
161
@@ -188,15 +184,14 @@ angular.module('angular-meteor.reactive', ['angular-meteor.reactive-scope']).fac
188
184
}
189
185
}
190
186
191
- return function ( context ) {
192
- let instance = new ReactiveContext ( context ) ;
187
+ return function ( context ) {
188
+ let reactiveContext = new ReactiveContext ( context ) ;
193
189
194
- context . helpers = instance . helpers . bind ( instance ) ;
195
- context . attach = instance . attach . bind ( instance ) ;
196
- context . stop = instance . stop . bind ( instance ) ;
197
- context . autorun = instance . autorun . bind ( instance ) ;
198
- context . subscribe = instance . subscribe . bind ( instance ) ;
190
+ // manipulates the original context so it could access reactive methods
191
+ _ . keys ( ReactiveContext . prototype )
192
+ . filter ( ( k ) => k . charAt ( 0 ) != '_' )
193
+ . forEach ( ( k ) => context [ k ] = reactiveContext [ k ] . bind ( reactiveContext ) ) ;
199
194
200
- return instance ;
195
+ return reactiveContext ;
201
196
} ;
202
197
} ] ) ;
0 commit comments