AngularJS : Differences among = & @ in directive scope?
在指令内创建一个隔离作用域让我们可以将外部作用域映射到内部作用域。我们已经看到六种不同的映射方式:
这些作用域映射选项的作用是什么?
这可能会令人困惑,但希望有一个简单的例子可以澄清这一点。首先,让我们将模型绑定与行为分离。
下面是一个有助于将事物联系在一起的小提琴:http://jsfiddle.net/jeremylicness/3pvte/
并解释…如果您的指令如下:
1 | <my-directive target="foo"/> |
然后,您就有了范围的这些可能性:
1 | { target : '=' } |
这将把scope.target(指令)绑定到$scope.foo(外部作用域)。这是因为=用于双向绑定,当不指定任何内容时,它会自动将内部作用域上的名称与指令上的属性名称匹配。对scope.target的更改将更新$scope.foo。
1 | { bar : '=target' } |
这将把scope.bar绑定到$scope.foo。这是因为我们再次指定了双向绑定,但是告诉指令"target"属性中的内容应该在内部作用域中显示为"bar"。对scope.bar的更改将更新$scope.foo。
1 | { target : '@' } |
这会将scope.target设置为"foo",因为@的意思是"字面上理解"。对scope.target的更改不会传播到您的指令之外。
1 | { bar : '@target' } |
这将把scope.bar设置为"foo",因为@takes它的值来自target属性。对scope.bar的更改不会传播到指令之外。
现在让我们谈谈行为。让我们假设您的外部范围有:
1 | $scope.foo = function(parm1, parm2) { console.log(parm1 +":" + parm2); } |
有几种方法可以访问这个。如果您的HTML是:
1 | <my-directive target='foo'> |
然后
1 | { target : '=' } |
将允许您从指令中调用scope.target(1,2)。
同样的事情,
1 | { bar : '=target' } |
允许您从指令调用scope.bar(1,2)。
更常见的方法是将其确定为一种行为。从技术上讲,与符号和在父级上下文中计算表达式。这很重要。所以我可以:
1 | <my-directive target="a+b" /> |
如果父作用域有$scope.a=1和$scope.b=2,那么在我的指令中:
1 | { target: '&' } |
我可以调用scope.target(),结果是3。这一点很重要-绑定作为函数公开给内部作用域,但指令可以绑定到表达式。
更常见的方法是:
1 | <my-directive target="foo(val1,val2)"> |
然后您可以使用:
1 | { target: '&' } |
从指令中调用:
1 | scope.target({val1: 1, val2: 2}); |
这将获取您传递的对象,将属性映射到计算表达式中的参数,然后调用行为,本例中调用$scope.foo(1,2);
你也可以这样做:
1 | <my-directive target="foo(1, val)"/> |
这会将第一个参数锁定为literal 1,并从以下指令锁定:
1 | { bar: '&target' } |
然后:
1 | scope.bar(5) |
称为$scope.foo(1,5);
总结
如果目标dom属性的名称与隔离作用域属性名称匹配,则使用4、5和6。下面是一个有效的例子。
HTML1 2 3 4 5 6 7 | Outer Scope <input type="text" ng-model="myModel" /> <p> msg: {{ msg }} </p> Inner Scope |
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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: '&' } }; }); |