Xav*_*_Ex 10 angularjs angularjs-directive angularjs-scope
我知道我们通常通过一个独立的范围将函数传递给指令:
.directive('myComponent', function () {
return {
scope:{
foo: '&'
}
};
})
Run Code Online (Sandbox Code Playgroud)
然后在模板中我们可以像这样调用这个函数:
<button class="btn" ng-click="foo({ myVal: value })">Submit</button>
Run Code Online (Sandbox Code Playgroud)
父作用域中的myVal函数的参数名称在哪里foo.
现在,如果我打算从link函数而不是模板中使用它,我将不得不用:来调用它scope.foo()(value),因为它scope.foo充当原始函数的包装器.这对我来说似乎有点乏味.
如果我myComponent使用=以下函数将函数传递给指令:
.directive('myComponent', function () {
return {
scope:{
foo: '='
}
};
})
Run Code Online (Sandbox Code Playgroud)
然后我将能够使用scope.foo(value)我的链接功能.那么这是一个有效的用例,对函数使用双向绑定,还是我做了一些我不应该做的黑客攻击?
Joe*_*ger 19
这就是为什么我低估了答案.
首先,你不应该使用'='来传递对指令的函数引用.
'='创建两个监视并使用它们来确保指令范围和父范围引用是相同的(双向绑定).允许指令更改父作用域中函数的定义是一个非常糟糕的主意,这是使用此类绑定时发生的情况.此外,手表应尽量减少 - 虽然它会起作用,但两个额外的手表是不必要的.所以这不好 - 下来投票的一部分是建议它.
第二 - 答案错误地表示"&"的作用.&不是"单向约束".它只是因为,与'='不同,它不会创建任何$ watch,并且在指令范围内更改属性的值不会传播到父级.
根据文件:
&or&attr - 提供在父作用域的上下文中执行表达式的方法
在指令中使用&时,它会生成一个函数,该函数返回针对父作用域计算的表达式的值.表达式不必是函数调用.它可以是任何有效的角度表达式.此外,此生成的函数采用一个对象参数,该参数可以覆盖表达式中找到的任何局部变量的值.
要扩展OP的示例,假设父对象以下列方式使用此指令:
<my-component foo="go()">
Run Code Online (Sandbox Code Playgroud)
在指令(模板或链接功能)中,如果你打电话
foo({myVal: 42});
Run Code Online (Sandbox Code Playgroud)
你正在做的是评估表达式"go()",它恰好在父作用域上调用函数"go",不传递任何参数.
或者,
<my-component foo="go(value)">
Run Code Online (Sandbox Code Playgroud)
您正在评估父作用域上的表达式"go(value)",这将基本上调用$ parent.go($ parent.value)"
<my-component foo="go(myVal)">
Run Code Online (Sandbox Code Playgroud)
您正在评估表达式"go(myVal)",但在计算表达式之前,myVal将替换为42,因此计算的表达式将为"go(42)".
<my-component foo="myVal + value + go()">
Run Code Online (Sandbox Code Playgroud)
在这种情况下,$ scope.foo({myVal:42})将返回以下结果:
42 + $parent.value + $parent.go()
Run Code Online (Sandbox Code Playgroud)
从本质上讲,这种模式允许指令"注入"指令的使用者可以在foo表达式中选择使用的变量.
你可以这样做:
<my-component foo="go">
Run Code Online (Sandbox Code Playgroud)
并在指令中:
$scope.foo()(42)
Run Code Online (Sandbox Code Playgroud)
$ scope.foo()将计算表达式"go",它将返回对$ parent.go函数的引用.然后它将其称为$ parent.go(42).此模式的缺点是,如果表达式未计算函数,则会出现错误.
投票结果的最后一个原因是ng-event指令使用&的断言.事实并非如此.没有内置指令创建隔离范围:
scope:{
}
Run Code Online (Sandbox Code Playgroud)
'&foo'的实现是(为简单起见而简化),归结为:
$scope.foo = function(locals) {
return $parse(attr.foo)($scope.$parent, locals);
}
Run Code Online (Sandbox Code Playgroud)
ng-click的实现类似,但(也简化):
link: function(scope, elem, attr) {
elem.on('click', function(evt) {
$parse(attr.ngClick)(scope, {
$event: evt
}
});
}
Run Code Online (Sandbox Code Playgroud)
所以要记住的关键是当你使用'&'时,你没有传递一个函数 - 你正在传递一个表达式.该指令可以通过调用生成的函数随时获取此表达式的结果.
| 归档时间: |
|
| 查看次数: |
12083 次 |
| 最近记录: |