-
Notifications
You must be signed in to change notification settings - Fork 6
/
ComputedProperty.js
71 lines (70 loc) · 2.32 KB
/
ComputedProperty.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
define([
'dojo/_base/declare',
'./Property'
], function (declare, Property) {
return declare(Property, {
// dependsOn: Array
// This property declares the properties that this property it is computed
// from.
dependsOn: [],
getValue: function () {
// summary:
// This function should be implemented to provide custom computed properties
// When the corresponding property is accessed, this will be called with the
// the values of the properties listed in dependsOn as the arguments
},
// indicate that we have custom get functionality
hasCustomGet: true,
_get: function () {
var dependsOn = this.dependsOn || [this.name];
var args = [];
var parentObject = this._parent;
for (var i = 0; i < dependsOn.length; i++) {
var dependency = dependsOn[i];
args[i] = typeof dependency === 'object' ?
// the dependency is another reactive object
dependency.valueOf() :
// otherwise, treat it as a propery
dependency === this.name ?
// don't recursively go through getters on our own property
parentObject[this.name] :
// another property
parentObject.get(dependency);
}
return (this.value = this.getValue.apply(this, args));
},
_has: function () {
return true;
},
_addListener: function (listener) {
// TODO: do we want to wait on computed properties that return a promise?
var property = this;
var dependsOn = this.dependsOn || [this.name];
var handles = [];
function changeListener() {
// recompute the value of this property. we could use when() here to wait on promised results
property._queueChange(listener);
}
for (var i = 0; i < dependsOn.length; i++) {
// listen to each dependency
var dependency = dependsOn[i];
handles.push(typeof dependency === 'object' ?
// it is another reactive object
dependency.observe(changeListener, true) :
// otherwise treat as property
dependency === this.name ?
// setup the default listener for our own name
this.inherited(arguments, [changeListener]) :
// otherwise get the other property and listen
this._parent.property(dependsOn[i]).observe(changeListener, {onlyFutureUpdates: true}));
}
return {
remove: function () {
for (var i = 0; i < dependsOn.length; i++) {
handles[i].remove();
}
}
};
}
});
});