$watch 只在没有 watchExpression 的情况下工作

$watch is only working without a watchExpression

在我的 $onInit 我有一个 $watch:

public $onInit() {
    const name = this.$state.current.name;
    console.log(name);
    this.$scope.$watch(name, (oldVal, newVal) => {
        console.log(oldVal, newVal);
        console.log(this.$state.current.name;
    });
}

当我运行这段代码时oldVal, newVal都是undefined并且this.$state.current.name值在$watch范围内和外部是相同的

当我 运行 没有 name 表达式的代码时:

public $onInit() {
    const name = this.$state.current.name;
    console.log(name);
    this.$scope.$watch((oldVal, newVal) => {
        console.log(oldVal, newVal);
        console.log(this.$state.current.name);
    });
}

$watch不断运行。 oldValScope {$id: 353, .... etcnewVal 未定义。但是 this.$state.current.name 现在在 $watch 范围内更新。

所以 this.$scope.current.name 的值确实改变了。但是当我将它用作 $watch 中的表达式时,oldVal, newVal 都是未定义的并且 this.$state.current.name$watch.

中没有改变

看来我在 watchExpression 中做错了什么。有什么建议吗?

watchExpression 应该设置为一个字符串(即使它已经是一个字符串) 你试过了吗?

var name = 'some value'
this.$scope.$watch('name', (oldVal, newVal) => {
    console.log(oldVal, newVal);
    console.log(this.$state.current.name);
});

Documentation

这是 $watch 函数的预期行为。

来自文档

$watch(watchExpression, listener, [objectEquality]);
// watchExpression - can be `expression/function` 
// listener - callback
// objectEquality - deepWatch

$watch 函数在每个摘要周期 运行 上评估其 expression wrt $scope。所以在第一种方法中,你只是将 name 作为 string 传递,所以当摘要循环开始时,它会尝试评估 name 变量,这显然不存在于 $scope,这就是您每次 $watch 评估获得 undefined 价值的原因。

而在第二种方法中,您将 function/callback 传递给 $watch 函数。它在每个摘要周期 运行 上进行评估,这是错误的。你应该做的是,传递 callback 将 return this.$state.current.name 的函数,然后只有你会在 $watch 侦听器函数中获得所需的结果。


可以用下面的方法解决

this.$scope.$watch(() => {
   return this.$state.current.name
}, (oldVal, newVal) => {
    console.log(oldVal, newVal);
    console.log(this.$state.current.name;
});