ボタンを含むカスタムディレクティブを作成しました。このボタンは、「callback」属性で指定された親スコープからメソッドを呼び出します。
<!DOCTYPE html>
<html ng-app="app">
<head>
<title>Simple directive</title>
<script src="js/lib/angular/angular.js"></script>
<script type="text/javascript">
var app = angular.module('app', []);
app.controller('TestController', function($scope) {
$scope.doSomething = function(param) {
alert('Something called with: ' + param);
}
})
app.directive('myDirective', function() {
var ret = {
restrict: 'E',
scope: {
user: '@',
callback: '&' // bound a function from the scope
},
template: '<div>Hello {{user}}<button ng-show="hasCallback()" ng-click="callback({userData: user})">Callback</button>',
controller: function($scope) {
$scope.hasCallback2 = function() {
var t = typeof $scope.callback;
return t == 'function';
}
$scope.hasCallback = function() {
return angular.isDefined($scope.callback);
}
}
};
return ret;
});
</script>
</head>
<body ng-controller="TestController">
<my-directive user="cat" callback="doSomething(userData)"></my-directive>
<my-directive user="dog" callback="doSomething(userData)"></my-directive>
<my-directive user="pig"></my-directive>
</body>
</html>
私の質問は:
テンプレート内のボタンの可視性を制御するにはどうすればよいですか?カスタムタグでコールバック属性が指定されていない場合は非表示にします(3番目のmy-directiveタグを参照)。 typeofのコールバックをチェックすると、常に 'function'を取得し、angle.isDefined(...)もtrueを返します。
「&?」を使用する属性が設定されていない場合、undefinedを返します。
'&' =コールバック関数は常に定義されています。
「&?」 =コールバック関数は、htmlテンプレートで属性が定義されている場合にのみ定義されます。
bindToController: {
callback: '&?'
},
controller: function() {
if (this.callback === undefined) {
// attribute "callback" was not defined
}
}
注:Angular 1.4.8。で動作します。古いバージョンで動作するかどうかはわかりません。
Anglejsソースコードを見ると、これが見えます:
case '&':
parentGet = $parse(attrs[attrName]);
isolateScope[scopeName] = function(locals) {
return parentGet(scope, locals);
};
break;
parentGet
はバインドされた関数式です。残念ながら、これはローカル変数であり、クロージャーを介してisolateScope[scopeName]
に割り当てられた関数でのみ使用できます。
その変数を取得する方法を見つける代わりに、単純な解決策はattrs
をチェックすることです。試してください:
link: function(scope,elem,attrs) {
scope.hasCallback = function() {
return angular.isDefined(attrs.callback);
}
}