Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if a method argument of a directive is specified in AngularJS?

I've created a custom directive which contains a button. This button calls a method from parent scope specified by 'callback' attribute.

<!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> 

My question is:

How can I control visibility of button inside template? I'd like to hide it if callback attribute not specified in custom tag (see 3rd my-directive tag). When I check typeof of callback, I always get 'function' and angular.isDefined(...) also returns true.

like image 945
Ferenc T Avatar asked Feb 21 '14 12:02

Ferenc T


People also ask

How do you call a method in a directive?

Inside the directive it is creating an updateMap() method on the scope object in the directive and then calling the setFn() method which is mapped to the $scope. setDirectiveFn() method by this line: <map set-fn="setDirectiveFn(theDirFn)"></map> in your HTML and this line: scope: { setFn: '&' } in your directive.

What is $compile in AngularJS?

Overview. Compiles an HTML string or DOM into a template and produces a template function, which can then be used to link scope and the template together. The compilation is a process of walking the DOM tree and matching DOM elements to directives.

Which of the directive is used to display text in AngularJS?

ng-app: The ng-app Directive in AngularJS is used to define the root element of an AngularJS application. This directive automatically initializes the AngularJS application on page load. It can be used to load various modules in AngularJS Application.

Which directive is used to specify Angular?

The ng-app directive defines the root element of an AngularJS application. The ng-app directive will auto-bootstrap (automatically initialize) the application when a web page is loaded.


2 Answers

Using '&?' returns undefined if the attribute has not been set.

'&' = callback function is defined always.

'&?' = callback function is defined only when attribute is defined in html template.

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

Note: Works in Angular 1.4.8. I'm not sure if it works in older versions.

like image 125
Bulki S Maslom Avatar answered Sep 21 '22 12:09

Bulki S Maslom


Looking at angularjs source code, I see this:

case '&':     parentGet = $parse(attrs[attrName]);     isolateScope[scopeName] = function(locals) {          return parentGet(scope, locals);     };     break; 

The parentGet is the bound function expression. Unfortunately, this is a local variable which is only available to the function assigned to isolateScope[scopeName] via closure.

Instead of trying to find a way to get that variable, a simple solution is just to check the attrs. Try:

link: function(scope,elem,attrs) {        scope.hasCallback = function() {         return angular.isDefined(attrs.callback);       }     } 

DEMO

like image 20
Khanh TO Avatar answered Sep 21 '22 12:09

Khanh TO