web-dev-qa-db-ja.com

AngularJSでディレクティブのメソッド引数が指定されているかどうかを確認する方法は?

ボタンを含むカスタムディレクティブを作成しました。このボタンは、「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を返します。

39
Ferenc T

「&?」を使用する属性が設定されていない場合、undefinedを返します。

'&' =コールバック関数は常に定義されています。

「&?」 =コールバック関数は、htmlテンプレートで属性が定義されている場合にのみ定義されます。

bindToController: {
    callback: '&?'
},
controller: function() {
    if (this.callback === undefined) {
        // attribute "callback" was not defined
    }
}

注:Angular 1.4.8。で動作します。古いバージョンで動作するかどうかはわかりません。

86
Bulki S Maslom

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);
      }
    }

[〜#〜] demo [〜#〜]

45
Khanh TO