我已经仔细阅读了AngularJS关于这个主题的文档,然后摆弄了一个指令。这是小提琴。
以下是一些相关片段:
来自HTML:
<窗格bi-title = "标题" title =“{{标题}}>{{文本}}> < /窗格
从窗格指令:
scope: {biTitle: '=', title: '@', bar: '='},
有几件事我不明白:
为什么我必须使用“{{title}}”与“@”和“title”与“=”?
我也可以直接访问父范围,而不装饰我的元素与属性?
文档说:“通常情况下,通过表达式将数据从孤立的作用域传递到父作用域是可取的”,但这似乎也适用于双向绑定。为什么表达式路由会更好呢?
我发现另一个小提琴,显示表达式解决方案太:http://jsfiddle.net/maxisam/QrCXh/
这里有很多很好的答案,但我想就@、=和&绑定之间的差异提供我的观点,这对我来说很有用。
这三种绑定都是通过元素属性将数据从你的父作用域传递到你指令的隔离作用域的方法:
@ binding is for passing strings.
These strings support {{}} expressions for interpolated values.
For example:
. The interpolated expression is evaluated against
directive's parent scope.
= binding is for two-way model binding. The model in parent scope
is linked to the model in the directive's isolated scope. Changes to
one model affects the other, and vice versa.
& binding is for passing a method into your directive's scope so that
it can be called within your directive. The method is pre-bound to
the directive's parent scope, and supports arguments. For example if the method is hello(name) in parent scope, then in
order to execute the method from inside your directive, you must
call $scope.hello({name:'world'})
我发现通过一个更短的描述来参考作用域绑定更容易记住这些区别:
@属性字符串绑定
=双向模型绑定
&回调方法绑定
这些符号还可以更清楚地说明作用域变量在指令实现中的含义:
@字符串
=模型
&方法
按用处排序(至少对我来说):
=
@
&
我创建了一个小的HTML文件,里面有Angular代码来演示它们之间的区别:
<!DOCTYPE html>
<html>
<head>
<title>Angular</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
</head>
<body ng-app="myApp">
<div ng-controller="myCtrl as VM">
<a my-dir
attr1="VM.sayHi('Juan')" <!-- scope: "=" -->
attr2="VM.sayHi('Juan')" <!-- scope: "@" -->
attr3="VM.sayHi('Juan')" <!-- scope: "&" -->
></a>
</div>
<script>
angular.module("myApp", [])
.controller("myCtrl", [function(){
var vm = this;
vm.sayHi = function(name){
return ("Hey there, " + name);
}
}])
.directive("myDir", [function(){
return {
scope: {
attr1: "=",
attr2: "@",
attr3: "&"
},
link: function(scope){
console.log(scope.attr1); // =, logs "Hey there, Juan"
console.log(scope.attr2); // @, logs "VM.sayHi('Juan')"
console.log(scope.attr3); // &, logs "function (a){return h(c,a)}"
console.log(scope.attr3()); // &, logs "Hey there, Juan"
}
}
}]);
</script>
</body>
</html>
如果您想通过一个现场示例了解更多这是如何工作的。http://jsfiddle.net/juanmendez/k6chmnch/
var app = angular.module('app', []);
app.controller("myController", function ($scope) {
$scope.title = "binding";
});
app.directive("jmFind", function () {
return {
replace: true,
restrict: 'C',
transclude: true,
scope: {
title1: "=",
title2: "@"
},
template: "<div><p>{{title1}} {{title2}}</p></div>"
};
});
即使作用域是本地的,就像在您的例子中,您也可以通过属性$parent访问父作用域。假设在下面的代码中,标题是在父作用域上定义的。然后你可以通过$parent.title访问title:
link : function(scope) { console.log(scope.$parent.title) },
template : "the parent has the title {{$parent.title}}"
但是,在大多数情况下,使用属性可以更好地获得相同的效果。
我发现“&”符号的一个例子是在ng-repeat中渲染特殊数据结构的指令中,它用于“通过表达式将数据从隔离作用域传递到父作用域”,很有用(并且不能使用双向数据绑定)。
<render data = "record" deleteFunction = "dataList.splice($index,1)" ng-repeat = "record in dataList" > </render>
渲染的一部分是删除按钮,这里通过&从外部作用域附加一个删除函数很有用。在渲染指令中,它是这样的
scope : { data = "=", deleteFunction = "&"},
template : "... <button ng-click = "deleteFunction()"></button>"
2-way数据绑定,即data =" ="不能被使用,因为delete函数会在每个$digest周期上运行,这是不好的,因为记录会立即被删除,并且永远不会呈现。