为什么ReactiveVar没有equals方法?

时间:2014-09-09 08:06:32

标签: meteor

我看到使用Session.equals('key', 'someValue')支持Session.get('key') == 'someValue'的好处,但不应该同样适用于ReactiveVar?为什么没有equals方法?

包中的评论说:

  

这个课程现在非常基础,但我们的想法是不断发展   它进入了Geoff的Lickable Forms提案的ReactiveVar。

它还没有实现吗?

2 个答案:

答案 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();
}