在看angular的一個小項目時,遇到了一個問題, 就是在創建directive的時候, 對於新scope的創建上.
html代碼如下
<!doctype html>
<html lang="en" ng-app="demoApp">
<head>
<meta charset="UTF-8">
<title>angular test</title>
<style>
.demo1, .demo2{
width: 200px;
height: 200px;
border: 1px solid #ccc;
text-align: center;
line-height: 200px;
}
</style>
</head>
<body>
<div id="output"></div>
<div ng-controller="demoCtrl">
<demo x-cbk1="cbk1(arg1, arg2)" x-cbk2="cbk2"></demo>
</div>
<script src="http://cdn.staticfile.org/angular.js/1.2.16/angular.js"></script>
<script src="demoapp.js"></script>
</body>
</html>
js代碼如下
angular.module('demoApp', [])
.controller('demoCtrl', function($scope) {
var output = angular.element(document.getElementById('output'));
$scope.cbk1 = function(arg1, arg2) {
output.html('click demo1, calls cbk1, arg1: ' + arg1 + ' arg2: ' + arg2);
};
$scope.cbk2 = function(arg1, arg2) {
output.html('click demo2, calls cbk2, arg1: ' + arg1 + ' arg2: ' + arg2);
};
})
.directive('demo', function(){
return {
restrict: 'E',
replace: true,
template: '<div><div class="demo1">demo1</div><div class="demo2">demo2</div></div>',
scope: {
cbk1: '&',
cbk2: '='
},
link: function(scope, element){
console.log('cbk1 string:', scope.cbk1);
console.log('cbk2 string:', scope.cbk2);
var demos = element.children();
var demo1 = demos.eq(0);
var demo2 = demos.eq(1);
demo1.on('click', function(){
scope.cbk1({
// 這裡的調用方法需要注意, 不是使用參數列表, 而是使用object的方法
arg1: 'cbk1 arg1',
arg2: 'cbk1 arg2'
});
});
demo2.on('click', function(){
// 同原函數一樣進行調用即可
scope.cbk2('cbk2 arg1', 'cbk2 arg2');
});
}
};
});
可以看到, scope的兩個cbk函數其實是一樣的, 只是在從demo這個directive向template中的scope傳遞的時候並不一樣, 傳遞cbk1的時候用的是 &
, 傳遞cbk2的時候用的是=
.
這樣, 在template的新scope中, 接收到的cbk2是demo這個directive中的一個原樣拷貝, 但是cbk1就不是了, 可以從上面獲取兩個函數的字符串表示中看到.
cbk1的字符串表示是
function (locals) {
return parentGet(scope, locals);
}
cbk2的字符串表示是
function (arg1, arg2) {
output.html('click demo2, calls cbk2, arg1: ' + arg1 + ' arg2: ' + arg2);
}
證明上面說的是正確的.
但是看angular官方文檔的時候, 寫的是, 如果需要傳遞一個callback的時候, 推薦使用&
.
這裡我的看法是, 如果這個callback不需要傳遞參數的話, 兩種方法都沒有問題.
如果需要向這個callback傳遞參數的話,我習慣上還是用=
, 因為這裡獲取的function是一個原來函數的引用, 而不是經過angular包裝的方法, 調用這個function的時候會更加符合函數的寫法.
如果使用&
的話, 調用函數就需要注意. 在上面html代碼x-cbk1="cbk1(arg1, arg2)"
中, cbk1的調用方法是cbk1(arg1, arg2)
, 所以在調用這個方法就需要注意傳遞參數的正確. 在link中click回調中, 參數的傳遞方法是使用object, 而不是普通的參數列表的方法. key值是x-cbk1="cbk1(arg1, arg2)"
中的形參的名字, 不能使用其它的名字.