Javascript 角度$watch |从函数返回项目

Javascript 角度$watch |从函数返回项目,javascript,angularjs,Javascript,Angularjs,我很想知道为什么我总是这么做 $scope.$watch( function() { return $scope.someData; }, function( value ) { console.log( value ); }); 对于angular来说,要真正观察数据,为什么我必须这样做,这是真正困扰我的事情之一,因为它看起来毫无意义 如果我做这样的事 $scope.$watch($scope.someData, function( value ) { console.lo

我很想知道为什么我总是这么做

$scope.$watch( function() {
   return $scope.someData;
}, function( value ) {
   console.log( value );
});
对于angular来说,要真正观察数据,为什么我必须这样做,这是真正困扰我的事情之一,因为它看起来毫无意义

如果我做这样的事

$scope.$watch($scope.someData, function( value ) {
   console.log( value );
});
哪一个更好,它永远不起作用

我也经常在工厂里用这个

假设
$data
是我必须做的工厂

$scope.$watch( function() {
   return $data.someData;
}, function( value ) {
   console.log( value );
});
这项工作:

$scope.$watch("someData", function( value ) {
   console.log( value );
});

对于工厂,您需要观察函数,因为如果传递字符串,Angular将根据$scope将其作为表达式进行计算。由于$data.someData未在$scope上定义,因此它将无法工作

要详细说明@Codezilla的评论,您可以将工厂数据分配给某个$scope属性,然后观察:

$scope.data = $data.someData;
$scope.$watch('data', function(newValue) { ... });

我想值得一提的是,将函数传递给
$watch
在您想要监视某个条件时非常有用:

$scope.$watch(function() { 
    return $scope.data.length > 0; 
}, function() {
    // Do something every time $scope.data.length > 0 changes
});


既然已经给出了“如何做”的答案,我将尝试向您解释实际发生了什么,以及为什么它没有按照您第一次尝试的方式工作

首先,这些代码确实有效

$scope.$watch(function() {
   return $scope.someData;
}, function(value) {
   console.log(value);
});
但这不是完美的方式。更准确地说,
$watch
在函数中注入
作用域
,如下所示

$scope.$watch(function(injectedScope) {
   return injectedScope.someData;
}, function(value) {
   console.log(value);
});
以前它之所以有效是因为
$scope
injectScope
是一回事

正如这所解释的

由于
$scope
被传递到watch函数中,这意味着我们可以 观察任何期望范围作为参数并返回 响应值。这方面的一个很好的例子是 功能

因此,在您的情况下,我们还可以使用
$interpolate
,如下所示:

$scope.$watch($interpolate("{{someData}}"), function(value) {
    ...
});
这就是我们使用手表表达式的简写方法。
$watch
也可以接受表达式,该表达式实际上是插值的

因此,通过提供
$scope.$watch(“someData”,…)

某些数据将是:

  • 插值为
    {{someData}}
  • 使用
    $watch
    函数注入的范围

  • 这是一种编写表达式而不是实际函数的漂亮、干净、可读、快捷的方法。但最后,在所有这些编译之后,最终是函数返回一个要监视的值。

    do:
    $scope.$watch('someData',函数(…
    Cool,那么工厂呢?我想你可以将工厂返回分配给一个模型并观察该模型。我刚刚在代码中重新编写了注释。回调函数会在条件每次更改时调用,而不是每次变为真时调用。在第二个示例中,每当条件正确更改时,它都会触发。不是两者都是这样吗每当
    $scope.prop1&&$scope.prop2
    发生变化时,t将触发。如果一方发生变化,但整个条件没有变化,则不会触发。例如,如果
    $scope.prop1
    $scope.prop2
    都为false,并且其中一方变为true,则表达式仍为false,并且不会调用watch回调。@MichaelBenford Hey Michael!这是我没有得到的angualr应用程序的一部分:
    $scope.$watch(函数(){return$scope.model&&$scope.model.Test&&$scope.model.Test.AnotherTest;},函数(value){if(value){doSomething();})根据您的解释,所有这些条件都应该减少到
    $scope.model.Test.AnotherTest;
    对吗?
    $scope.$watch($interpolate("{{someData}}"), function(value) {
        ...
    });