我看到使用Session.equals('key', 'someValue')
支持Session.get('key') == 'someValue'
的好处,但不应该同样适用于ReactiveVar
?为什么没有equals
方法?
包中的评论说:
这个课程现在非常基础,但我们的想法是不断发展 它进入了Geoff的Lickable Forms提案的ReactiveVar。
它还没有实现吗?
答案 0 :(得分:1)
如果查看source,您会看到它目前尚未实施。有趣的是,您可以在创建实例时传入自定义equalsFunc
,尽管它目前仅用于依赖关系跟踪。
这可能是正确的,所以equals
暂时被跳过了。目前,如果您想自己添加,可以使用以下内容修补ReactiveVar
:
_.defaults(ReactiveVar.prototype, {
equals: function(value) {
return _.isEqual(this.get(), value);
}
});
这使用下划线的isEqual,这可能是一个很好的默认值。请注意,如果equals
在将来某个日期可用,defaults将阻止修补程序的应用。
我测试了它:
var v = new ReactiveVar();
v.set({fancy: 'pantz'});
Tracker.autorun(function() {
if (v.equals({fancy: 'pants'})) {
console.log('HORAY!');
}
});
Meteor.setTimeout((function() {
v.set({fancy: 'pants'});
}), 1000);
请注意,与Session.equals
不同,依赖关系将在任何更改后重新运行(而不是仅在满足相等条件时)。
答案 1 :(得分:0)
这里是ReactiveVar的equals()实现,它将以与ReactiveDict.equals()相同的方式避免冗余重新运行:
ReactiveVar.prototype.equals = function(comparisonValue) {
var self = this;
var isEqual = self.equalsFunc || ReactiveVar._isEqual;
// don't bother storing dependencies if executing outside a computation
if (!Tracker.active) {
return isEqual(self.curValue, comparisonValue);
}
// make sure we have a place to put dependencies for each comparisonValue
if (!_.has(self, "equalsDeps"))
self.equalsDeps = {};
var valueString = (comparisonValue === undefined)
? "undefined"
: EJSON.stringify(comparisonValue);
if (! _.has(self.equalsDeps, valueString))
self.equalsDeps[valueString] = new ReactiveVar();
// This gets run every time the variable value changes
Tracker.autorun( function() {
// If newEqualityValue is unchanged, nothing happens in the set(), and
// nothing more needs to be calculated. It's this that filters out
// the unnecessary reruns.
var newEqualityValue = isEqual(self.get(), comparisonValue);
self.equalsDeps[valueString].set(newEqualityValue);
});
Tracker.onInvalidate( function() {
// Check if there are any remaining computations that depend on
// equalling this value. If not, remove the dependency to keep
// from using memory for every value ever compared against.
//
// This needs to be done in an afterFlush because tracked
// dependents aren't updated till after onInvalidate callbacks
// are called.
Tracker.afterFlush( function() {
if (self.equalsDeps[valueString] && !self.equalsDeps[valueString].dep.hasDependents()) {
delete self.equalsDeps[valueString];
}
});
});
// This get() returns the comparison calculated in the above autorun, and
// invalidates the enclosing computation if that value changed (from true
// to false, say). This triggers the necessary reruns.
return self.equalsDeps[valueString].get();
}