2014-02-21 41 views
36

我创建了一个包含按钮的自定义指令。这个按钮从'callback'属性指定的父作用域中调用一个方法。如何检查AngularJS中是否指定了指令的方法参数?

<!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的回调,我总是得到'功能'和angular.isDefined(...)也返回true。

+0

检查指令的链接函数中的attrs数组 –

回答

45

综观angularjs源代码,我看到:

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

+0

帮助,谢谢。 –

+2

@Ferenc T:你可以将答案标记为接受,如果它可以帮助你。谢谢 –

+0

帮助了我,但不是'angular.isDefined'我更喜欢vanilla-js'attrs.hasOwnProperty('callback');' – Stalinko

79

使用'&?如果属性尚未设置,则返回undefined。

'&'=总是定义回调函数。

'&?' =回调函数仅在html模板中定义属性时定义。

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

注意:适用于Angular 1.4.8。我不确定它是否适用于旧版本。

+1

真棒!从来没有读过这个 – CodeNashor

+2

这工作完美,是一个更优雅的解决方案。应该是正确的答案。 – Rebecca

+0

[文档](https://docs.angularjs.org/api/ng/service/$compile#-scope-)中没有关于它的单词。 – fracz