AngularJS:指令范围内=&@之间的差异?
在指令中创build一个隔离范围让我们将外部范围映射到内部范围 。 我们已经看到了六种不同的方式来映射到属性:
- =属性
- &ATTR
- @attr
- =
- &
- @
每个这些示波器映射选项都做什么?
这可能会令人困惑,但希望一个简单的例子可以澄清它。 首先,我们将模型绑定与行为分开。
这是一个小提琴,应该帮助把事情联系在一起: 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)。
更常见的方式是将其作为一种行为。 从技术上讲,&符号评估父级上下文中的expression式。 这很重要。 所以我可以有:
<my-directive target="a+b" />
如果父范围有$ scope.a = 1和$ scope.b = 2,那么在我的指令中:
{ target: '&' }
我可以调用scope.target(),结果将是3.这很重要 – 绑定作为一个函数暴露给内部作用域,但指令可以绑定到一个expression式。
更常见的做法是:
<my-directive target="foo(val1,val2)">
那么你可以使用:
{ target: '&' }
并从指令中调用:
scope.target({val1: 1, val2: 2});
这需要你传递的对象,将属性映射到评估expression式中的参数,然后调用行为,这种情况下调用$ scope.foo(1,2);
你也可以这样做:
<my-directive target="foo(1, val)"/>
这将第一个参数locking在文字1中,并从该指令中locking:
{ bar: '&target' }
然后:
scope.bar(5)
这将调用$ scope.foo(1,5);
概要
- @attr绑定到匹配的DOM属性的评估string值。
- = attr绑定到匹配的DOM属性的范围属性 。
- &attr绑定到匹配的DOM属性的作用域函数 。
- @
- =
- &
如果目标DOM属性的名称与隔离作用域名称匹配,则使用4,5和6 。 下面的例子是一个工作的小提琴 。
HTML
<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>
使用Javascript
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: '&ersand', at: '@', equals: '=', ampersand: '&' } }; });