AngularJS:指令范围内的=和@之间的差异?



在指令中创建隔离作用域可以让我们将外部作用域映射到内部作用域。我们已经看到了六种不同的映射到吸引的方式:

  1. =吸引力
  2. 和吸引力
  3. @attr
  4. =
  5. &
  6. @

这些范围映射选项中的每一个都有什么作用?

这可能会令人困惑,但希望一个简单的例子可以澄清它。首先,让我们将模型绑定与行为分开。

这里有一个小提琴,应该有助于将事情联系在一起:http://jsfiddle.net/jeremylikness/3pvte/

并解释...如果您的指令如下所示:

<my-directive target="foo"/> 

然后,您有以下范围的可能性:

{ target : '=' } 

这会将 scope.target(指令)绑定到 $scope.foo(外部作用域)。这是因为 = 用于双向绑定,当您不指定任何内容时,它会自动将内部作用域上的名称与指令上的属性名称匹配。对 scope.target 的更改将更新 $scope.foo。

{ bar : '=target' } 

这会将 scope.bar 绑定到 $scope.foo。这是因为我们再次指定双向绑定,但告诉指令属性"target"中的内容应该在内部范围内显示为"bar"。对 scope.bar 所做的更改将更新$scope.foo。

{ target : '@' } 

这会将 scope.target 设置为"foo",因为 @ 表示"从字面上理解"。对 scope.target 的更改不会传播到指令之外。

{ bar : '@target' } 

这会将 scope.bar 设置为"foo",因为 @ 从目标属性中获取其值。对 scope.bar 所做的更改不会传播到指令之外。

现在让我们谈谈行为。假设您的外部作用域具有以下内容:

$scope.foo = function(parm1, parm2) { console.log(parm1 + ": " + parm2); } 

您可以通过多种方式访问它。如果您的 HTML 是:

<my-directive target='foo'>

然后

{ target : '=' } 

将允许您从指令调用 scope.target(1,2)。

同样的事情,

{ bar : '=target' }

允许您从指令调用 scope.bar(1,2)。

更常见的方法是将其建立为一种行为。从技术上讲,& 符号在父项的上下文中计算表达式。这很重要。所以我可以有:

<my-directive target="a+b" />

如果父范围有 $scope.a = 1 和 $scope.b = 2,那么在我的指令上:

{ target: '&' } 

我可以调用scope.target(),结果将是3。这很重要 - 绑定作为函数公开给内部作用域,但指令可以绑定到表达式。

更常见的方法是:

<my-directive target="foo(val1,val2)"> 

然后,您可以使用:

{ target: '&' }

并从指令中调用:

scope.target({val1: 1, val2: 2}); 

这将获取您传递的对象,将属性映射到计算表达式中的参数,然后调用行为,在这种情况下调用 $scope.foo(1,2);

您也可以这样做:

<my-directive target="foo(1, val)"/>

这会将第一个参数锁定到文字 1,并从指令中锁定:

{ bar: '&target' }

然后:

scope.bar(5) 

这将调用$scope.foo(1,5);

总结

  1. @attr绑定到匹配的 DOM 属性的计算字符串值。
  2. =attr绑定到匹配的 DOM 属性的范围属性
  3. &attr绑定到匹配的 DOM 属性的作用域函数
  4. @
  5. =
  6. &

如果目标 DOM 属性的名称与隔离范围属性名称匹配,则使用4、5 和 6。这是以下示例的工作小提琴

目录

<div ng-app='isolate'>
<h3>Outer Scope</h3>
<input type="text" ng-model="myModel" />
<p>msg: {{ msg }}</p>
<h3>Inner Scope</h3>
<div id="inner">
<div my-directive at="{{ myModel }}" equals="myModel" ampersand="msg=msg+'click'"></div>
</div>
</div>

爪哇语

angular.module('isolate', [])
.directive('myDirective', function () {
return {
template:
'<label>@attr</label><input value="{{ myAt }}" />' +
'<label>@</label><input value="{{ at }}" />' +
'<label>=attr</label><input ng-model="myEquals" />' +
'<label>=</label><input ng-model="equals" />' +
'<label>&attr</label><input type="button" ng-click="myAmpersand()" value="Btn" />' +
'<label>&</label><input type="button" ng-click="ampersand()" value="Btn" />',
scope: {
myAt: '@at',
myEquals: '=equals',
myAmpersand: '&ampersand',
at: '@',
equals: '=',
ampersand: '&'
}
};
});

最新更新