在NodeJS中创建类似KnockoutJS的跟踪器

时间:2014-05-21 04:19:17

标签: javascript node.js knockout.js key-value-observing observable

所以我基本上只是试图将观察者添加到Javascript的Getter / Setter功能中,但还没有运气。

KnockoutJS(http://knockoutjs.com)使用.track()执行此操作。

正在使用track()的YouTube视频示例:
https://www.youtube.com/watch?v=MNiUcuo3Wio

这引出了我的第一个问题, __defineGetter____defineSetter__只适用于对象而非字符串文字吗?

以下是一个代码示例,说明了理想情况下如何工作,它可能会澄清一些事情。

// Knockout-like tracker in NodeJS.

function track(trackObj, callback) {

  if (!trackObj) return;

  trackObj.__defineCallback__ = callback;

  trackObj.__defineGetter__('value', function() {
    return 'something';
  });

  trackObj.__defineSetter__('value', function() {
    console.log("fn called");
    if (trackObj.__defineCallback__)
      trackObj.__defineCallback__("new value");
  });

}

var something = "track me!";

track(something, function(newValue) {
  console.log("Something has changed to: " + newValue);
});

something = "I have changed."; // Trigger the update callback function.

1 个答案:

答案 0 :(得分:0)

我已经创建了一个简单的解决方案,尽管我对此并不满意。出于这个原因,我现在暂时没有回答这个问题。

缺点之一是您只能跟踪具有相同名称的单个属性。为了解决这个问题,您可以将以下代码放在NodeJS模块中,并为您要跟踪的每个项目创建一个新的跟踪器对象。这也适用于相同的命名变量。处理所有不同的跟踪器对象可能会让人感到困惑。

var tracker = {};
var trackerValues = {};

function track(trackName, callback) {

  Object.defineProperty(tracker, trackName, {

    set: function(toValue) {
      trackerValues[trackName] = toValue;
      if (callback) callback();
    },

    get: function() {
      return trackerValues[trackName];
    }

  });
}

tracker.something = "track me!";

track("something", function() {
  console.log("Something has changed to: " + tracker.something);
});

track("somethingElse", function() {
  console.log("SomethingElse has changed to: " + tracker.somethingElse);
});

tracker.something = "I have changed.";
tracker.something = "I have changed again!";
tracker.somethingElse = "We can track multiple objects";

和这个工作的一个JSBin例子:
http://jsbin.com/bunonaca/1/edit?js,console