【问题标题】:Passing jqLite .html() handle directly as an AngularJS watch listener将 jqLit​​e .html() 句柄直接作为 AngularJS 监听器传递
【发布时间】:2026-01-16 08:25:01
【问题描述】:

我正在尝试将 jqLit​​e 函数 element.html 直接作为观察者的侦听器传递:

angular.module('testApp', []).directive('test', function () {
  return {
    restrict: 'A',
    link: function (scope, element, attrs) {
      scope.$watch('someVariable', element.html); // <-- Passing the function handle as listener
    }
  };
});

但是由于某种原因这不起作用,因此作为一种解决方法,我将侦听器包装在一个函数中:

angular.module('testApp', []).directive('test', function () {
  return {
    restrict: 'A',
    link: function (scope, element, attrs) {
      scope.$watch('someVariable', function (newValue) {
        element.html(newValue);
      });
    }
  };
});

第二个例子有效。

我不明白为什么第一个示例被破坏了。有什么想法吗?

编辑: 我忘了提,浏览器没有给我任何错误。它只是向我显示了一个空元素。

【问题讨论】:

  • 是的,请阅读 $watch 文档docs.angularjs.org/api/ng/type/$rootScope.Scope#$watch 监听器必须是一个函数而不是字符串或元素
  • 你想实现什么传递元素 html?
  • 据我了解typeof element.html 返回function,所以这应该没问题。我只是想省略包装功能,但很困惑为什么这不起作用。
  • 该函数虽然返回一个字符串..所以它不会做任何事情...请参阅下面的解释。

标签: javascript angularjs jqlite


【解决方案1】:

其实是因为angular的注入器会自动改变函数的this属性,考虑一下:

var test = function(string) {
    return {
        html: function(value) {
            console.log(this);
        }
    }
}

$scope.$watch('my_watch_expression', test('string').html);

当您检查 this 的值时,您会得到以下结果:

如你所见,它会在jQuery库上抛出错误:

this 没有empty 函数,因此,它会抛出一个静默异常并且不会按预期工作。

【讨论】:

  • 这对我帮助很大,谢谢!所以我只需要修复this,现在一切都很好:scope.$watch('my_watch_expression', element.html.bind(element));
【解决方案2】:

在官方文档中,https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$watch

$watch 中的第二个参数是监听器

"The listener is called only when the value ..."

从逻辑上讲,如果侦听器被“调用”,它必须是一个函数......或者我在这里错了。

当你这样做时:

link: function (scope, element, attrs) {
  scope.$watch('someVariable', element.html); // <-- Passing the function handle as listener
}

它查看在链接函数中传递的元素并尝试访问 .html 属性。它可能是一个函数,但它返回一个字符串......因此它成功运行,但不做任何日志记录,因为等效的是:

scope.$watch('someVariable', "<div> some content </div>"); 

这不会做任何事情,但不会导致任何错误。

如果你像以前一样将它包装在一个函数中,那么你可以用它做一些事情。

【讨论】:

  • 不等于scope.$watch('someVariable', "&lt;div&gt;some content&lt;/div&gt;");scope.$watch('someVariable', element.html()); 吗?在原始代码中,我只传递函数而不执行它。否则此代码也不起作用:scope.$watch('someVariable', listenerFn); function listenerFn (newValue) { element.html(newValue); }
  • 所以你问为什么当你将一个返回字符串的函数的函数句柄作为一个监听器传递给 angular. Angular 在哪里期望某种类型的函数格式作为侦听器传入?