Skip to content

Commit 31a7366

Browse files
committed
Merge pull request Urigo#923 from Urigo/feature/1.3-compatible
Feature/1.3 compatible
2 parents 26b40d0 + 9fa08d1 commit 31a7366

File tree

1 file changed

+67
-72
lines changed

1 file changed

+67
-72
lines changed

packages/angular-meteor-data/modules/angular-meteor-reactive-context.js

Lines changed: 67 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ angular.module('angular-meteor.reactive', ['angular-meteor.reactive-scope']).fac
77

88
this.context = context;
99

10-
if ((this.context.constructor || angular.noop).toString().indexOf('Scope') > -1) {
10+
if (this._isScope(this.context)) {
1111
this.scope = this.context;
1212
}
1313

@@ -16,19 +16,24 @@ angular.module('angular-meteor.reactive', ['angular-meteor.reactive-scope']).fac
1616
}
1717

1818
attach(scope) {
19-
if (!this.scope && (scope.constructor || angular.noop).toString().indexOf('Scope') > -1) {
19+
if (!this.scope && this._isScope(scope)) {
2020
this.scope = scope;
2121
}
2222

2323
return this;
2424
}
2525

26+
_isScope(obj) {
27+
return obj instanceof Object.getPrototypeOf($rootScope).constructor;
28+
}
29+
2630
_handleCursor(cursor, name) {
2731
if (angular.isUndefined(this.context[name])) {
28-
this._declareReactiveProperty(name, cursor.fetch());
32+
this._setValHelper(name, cursor.fetch());
2933
}
3034
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);
3237
}
3338

3439
let initial = true;
@@ -40,7 +45,8 @@ angular.module('angular-meteor.reactive', ['angular-meteor.reactive-scope']).fac
4045
}
4146
},
4247
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);
4450
this._propertyChanged(name);
4551
},
4652
movedTo: (doc, fromIndex, toIndex) => {
@@ -60,95 +66,84 @@ angular.module('angular-meteor.reactive', ['angular-meteor.reactive-scope']).fac
6066

6167
_handleNonCursor(data, name) {
6268
if (angular.isUndefined(this.context[name])) {
63-
this._declareReactiveProperty(name, data);
69+
this._setValHelper(name, data);
6470
}
6571
else {
6672
if ((!_.isObject(data) && !_.isArray(data)) ||
6773
(!_.isObject(this.context[name]) && !_.isArray(this.context[name]))) {
6874
this.context[name] = data;
6975
}
7076
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);
7279
this._propertyChanged(name);
7380
}
7481
}
7582
}
7683

77-
static _isMeteorCursor(obj) {
78-
return obj instanceof Mongo.Collection.Cursor;
79-
};
80-
8184
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);
12190
});
12291

12392
return this;
12493
}
12594

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);
13098

131-
Object.defineProperty(this.context, name, {
99+
Object.defineProperty(this.context, k, {
132100
configurable: true,
133101
enumerable: true,
134102

135-
get: function () {
136-
self.propertiesTrackerDeps[name].depend();
137-
return property;
103+
get: () => {
104+
this.propertiesTrackerDeps[k].depend();
105+
return v;
138106
},
139-
set: function (newValue) {
140-
property = newValue;
141-
self.propertiesTrackerDeps[name].changed();
107+
set: (newValue) => {
108+
v = newValue;
109+
this.propertiesTrackerDeps[k].changed();
142110
}
143111
});
144112
}
145113

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) {
147142
if (this.scope && !$rootScope.$$phase) {
148143
this.scope.$digest();
149144
}
150145

151-
this.propertiesTrackerDeps[propName].changed();
146+
this.propertiesTrackerDeps[k].changed();
152147
}
153148

154149
subscribe(name, fn) {
@@ -159,7 +154,8 @@ angular.module('angular-meteor.reactive', ['angular-meteor.reactive-scope']).fac
159154
}
160155
else {
161156
this.autorun(() => {
162-
this.stoppables.push(Meteor.subscribe(name, ...(fn() || [])));
157+
let args = fn() || [];
158+
this.stoppables.push(Meteor.subscribe(name, ...args));
163159
});
164160
}
165161

@@ -188,15 +184,14 @@ angular.module('angular-meteor.reactive', ['angular-meteor.reactive-scope']).fac
188184
}
189185
}
190186

191-
return function (context) {
192-
let instance = new ReactiveContext(context);
187+
return function(context) {
188+
let reactiveContext = new ReactiveContext(context);
193189

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));
199194

200-
return instance;
195+
return reactiveContext;
201196
};
202197
}]);

0 commit comments

Comments
 (0)