2014-09-09 3 views
0

Я вижу преимущества с использованием Session.equals('key', 'someValue') в пользу Session.get('key') == 'someValue', но не должны ли они применяться к ReactiveVar? Почему у него нет метода equals?Почему у ReactiveVar нет метода equals?

Комментарий в пакете говорит:

Этот класс является чрезвычайно основным прямо сейчас, но идея состоит в том, чтобы развивать его в ReactiveVar из Джеффа Lickable предложения форм.

Разве это еще не реализовано?

ответ

1

Если у вас есть source, вы увидите, что в настоящее время оно не реализовано. Интересно, что при создании экземпляра вы можете передать пользовательский код equalsFunc, хотя он в настоящее время используется только для отслеживания зависимостей. Возможно, было сложно, так как equals временно пропустили. На данный момент, если вы хотите добавить это самостоятельно, вы можете исправить ReactiveVar что-то вроде:

_.defaults(ReactiveVar.prototype, { 
    equals: function(value) { 
    return _.isEqual(this.get(), value); 
    } 
}); 

При этом используется подчеркивание'S 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, зависимость будет возобновлена ​​после любого изменения (а не только тогда, когда выполняется условие равенства выполняется).

+0

Но ваш 'equals' метод до сих пор вызывает излишние повторы, правильно? Если 'v' получил значение' 1', а один использует 'v.equals (5)' в автозапуске, автозапуск должен возобновляться только тогда, когда 'v' изменяет его значение на' 5'. С вашим решением, он повторно запускается, как сын, как 'v' изменяется на любое другое значение, не так ли? Трудно изменить его, чтобы он работал как 'ReactiveDict' (' Session')? –

+0

Вы правы - приведенный выше код заставит вычисление повторно запускаться после любых изменений, а не только после выполнения условия равенства. Может быть возможно оптимизировать отслеживание для скаляров, но не для объектов, без реализации «equalsFunc». Опять же, если вы только заботитесь о скалярах, вероятно, будет проще просто использовать «ReactiveDict» с постоянным ключом. –

+0

@DavidWeldon Как определить шаблон конкретных реактивных варов? – user1952811

0

Вот реализация Equals() для ReactiveVar, что позволит избежать лишних повторы таким же образом, что 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(); 
} 
Смежные вопросы