在 Angular 1.x 当 "watching" 指令中;为什么观察 returns 变量行为的函数与仅仅观察变量不同?
In Angular 1.x When "watching" in a directive; why does watching a function that returns a variable act different than just watching the variable?
解释这个问题的最简单方法是使用一些示例代码,所以这是一个用 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/isolated scope on: xxx
。
我的粗略猜测是它与闭包在 javascript 中的行为方式有关,但我无法理解两者的行为方式有何不同。
感谢您提供的任何见解。
scope.$watch
的界面根据 documentation 如下:
$watch(watchExpression, listener, [objectEquality]);
其中 watchExpression
是 string
或 function
。如果它是 string
,它会被解释为 scope
对象中的路径。假设 attributes.foo
是 "test.something"
,它将监视 scope.test.something
- 如果它存在。
如果您想观察 attributes.foo
值的变化,您必须使用 function
,或者将 attributes.foo
附加到您的范围并传递 "attributes.foo"
作为 watchExpression
.
解释这个问题的最简单方法是使用一些示例代码,所以这是一个用 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/isolated scope on: xxx
。
我的粗略猜测是它与闭包在 javascript 中的行为方式有关,但我无法理解两者的行为方式有何不同。
感谢您提供的任何见解。
scope.$watch
的界面根据 documentation 如下:
$watch(watchExpression, listener, [objectEquality]);
其中 watchExpression
是 string
或 function
。如果它是 string
,它会被解释为 scope
对象中的路径。假设 attributes.foo
是 "test.something"
,它将监视 scope.test.something
- 如果它存在。
如果您想观察 attributes.foo
值的变化,您必须使用 function
,或者将 attributes.foo
附加到您的范围并传递 "attributes.foo"
作为 watchExpression
.