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

在指令中创build一个隔离范围让我们将外部范围映射到内部范围 。 我们已经看到了六种不同的方式来映射到属性:

  1. =属性
  2. &ATTR
  3. @attr
  4. =
  5. @

每个这些示波器映射选项都做什么?

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

这是一个小提琴,应该帮助把事情联系在一起: 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);

概要

  1. @attr绑定到匹配的DOM属性的评估string值。
  2. = attr绑定到匹配的DOM属性的范围属性
  3. &attr绑定到匹配的DOM属性的作用域函数
  4. @
  5. =

如果目标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: '&ampersand', at: '@', equals: '=', ampersand: '&' } }; });