如何找到更改正在监视的对象的呼叫站点

时间:2013-12-11 00:25:28

标签: angularjs

AngularJS允许侦听对象的更改,并将调用提供给$ watch函数的提供的回调函数。使用AngularJS的大型库像ngGrid对象经常被更改为“被监视”。

一旦调用了监视回调,如何追溯导致对象更改的调用站点?

在不知道导致更改的原因的情况下,导致监视处理程序被调用,证明调试像ngGrid这样的库非常困难。我在任何地方设置断点我可以预见变量可以被更改,然后尝试为执行管道构建一个图形,以跟踪导致对象被更改的事件链。

2 个答案:

答案 0 :(得分:1)

你根本做不到。 $watch只会添加一个回调来检查对象是否已更改,以便在摘要期间运行。

我猜这是与Backbone这样的框架的主要区别之一,你可以扩展Model个对象。

话虽这么说,你可能有更好的运气试图$scope.$digest();故意(更新模型,解雇观察者),但这是一段时间......

更新

问题是你认为手表和模型变化之间存在关联,但根本没有。添加手表只会在摘要循环运行时添加要检查的内容。

$scope上某些内容的更改不会触发此循环,而是调用$scope.$apply或直接调用$scope.$digest

请注意,Angular指令和相关组件的大多数(全部?)代表您调用$scope.$apply。例如,$timeoutngClick按预期工作的原因是因为它们在执行回调后在内部运行$scope.$apply

更新II

如果您只是想找到呼叫站点,那么这样的事情会对您有所帮助吗?

$scope.foo = {
  get bar () { return getting(); },
  set bar (value) { setting(value); }
};

var bar;

function setting (value) {
  var stack = getStack();
  console.log(value, stack);
  bar = value;
}

function getting () {
  console.log(getStack());
}

function getStack () {
  try {
    throw new Error('foo');
  } catch (e) {
    return e.stack || e;
  }
}

result.png

答案 1 :(得分:0)

嗯,你现在可能已经找到了答案,但是因为我也在寻找它,而且找不到它所以我在这里发布答案。

我们假设您的javascript变量为name,并且您希望找到更改内容的人。

我找到的方法是:

  1. name更改为name_
  2. 添加getter:get name() { return this.name_ ; }
  3. 添加二传手:set name(value) { this.name_ = value ; }
  4. 在断路器中放置断点,并在触发断点时监视调用堆栈。
  5. 结构示例:

    <强>之前:

    scope = {
        name:'',
    };
    

    <强>后:

    scope = {
        name_:'',
        get name() { return this.name_; },
        set name(value) {
            this.name_ = value;
            alert('Changed!');
        },
    };
    

    我希望这会对你和其他人有所帮助!