javascript - 在 Angular 1.x 中当指令中有 "watching"时;为什么观察返回变量的函数与仅仅观察变量的行为不同?

标签 javascript angularjs angularjs-directive closures

解释这个问题的最简单方法是使用一些示例代码,所以这是一个用 ES6 语法编写的非常简单的指令:

export default class IsFoo {

  constructor() {
    // Set the directive properties
    this.restrict = 'A';
    this.require = 'ngModel';
  }

  link(scope, element, attributes, controller) {

    let foo = scope.$eval(attributes.foo);

    controller.$validators.isFooBar = (modelValue) => {

      // make sure we have the most recent value foo
      foo = attributes.foo;

        return foo === 'bar';
      };

      scope.$watch(() => {return attributes.foo;}, () => controller.$validate());
  }

  static directiveFactory() {
    IsFoo.instance = new IsFoo();
    return IsFoo.instance;
  }

}

IsFoo.directiveName = 'isFooBar';

这是我的指令的粗略版本,删除了所有实际重要的验证。它非常简单。

如果我将监视线更改为:

scope.$watch(attributes.foo), ()=>controller.$validate());

这是行不通的。为什么?为什么返回 attributes.foo 的函数有效?

导致最终结果不同的原因是什么?

另外,免责声明,我有意不使用范围隔离,因为该指令被用在一个元素上,该元素具有另一个使用范围隔离的指令。所以它们发生冲突,您会收到错误 Multiple directives asking for new/隔离范围:xxx

我的粗略猜测是它与闭包在 javascript 中的行为方式有关,但我无法理解这两者的行为方式有何不同。

感谢您提供的任何见解。

最佳答案

scope.$watch 的接口(interface)是根据 documentation以下内容:

$watch(watchExpression, listener, [objectEquality]);

watchExpression字符串函数。如果它是一个 string,它被解释为 scope 对象中的路径。假设 attributes.foo"test.something",它将监视 scope.test.something - 如果它存在。

如果你想观察attributes.foo值的变化,你必须使用函数,或者附上attributes.foo > 到您的范围并将 "attributes.foo" 作为 watchExpression 传递。

关于javascript - 在 Angular 1.x 中当指令中有 "watching"时;为什么观察返回变量的函数与仅仅观察变量的行为不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48119450/

相关文章:

c# - asp.net mvc Controller 无法识别 DateTime url 参数?

angularjs - 带编辑功能的 Angular 表

javascript - 在另一个指令中包装一个 ngRepeat

node.js - Angular.JS + Jade = Angular不处理jade的嵌入iframe

jquery - 使用 jQuery 在 AngularJS 元素指令上绑定(bind)事件

javascript - 使用 HTML5 视频元素且不使用 iframe 嵌入 Vimeo 视频

javascript - 在 iframe 中更改 iframe 的 src

javascript - 如何在两个 Angular 模块中使用相同的服务

javascript - 用json值替换angularjs中的部分字符串

javascript - 文本未定义 - JavaScript