How to check if an expression attribute has been provided in a directive?

I created a directive that accepts a callback as an attribute, for example:

<my-directive callback-expression="someFunction()"> </my-directive> 

The directive is reusable, and so I gave it a selection area. I want to show a button in a directive based on whether this callback-expression attribute is set.

 App.directive('myDirective', function(){ restrict: 'E', scope: { callbackExpression: '&' }, template: '<button ng-show="!!callbackExpression">Fire callback</button>' }); 

The problem is that this is a function, even if the expression is empty:

console.log($scope.callbackExpression) with an empty attribute results in:

 function (locals) { return parentGet(parentScope, locals); } 

My current solution is to have this line at the top of my link function:

 if (attributes.callbackExpression) scope.callbackButton = true 

Then ng-show on callbackButton

Are there any alternatives that do not require additional string properties and scope?

+6
source share
2 answers

If you want to not push anything onto the stack, you can use the link function, where you can access attributes through attrs . Here are two approaches to this:

Communication function 1 function:

Instead of using a template, you should use this link function in your directive, which conditionally adds your template:

 link: function (scope, element, attrs) { if (attrs.callbackExpression) { var html = '<button>Fire callback</button>'; element.replaceWith(html); } } 

Option 1: http://jsfiddle.net/ZC4MZ/2/

Link function 2 function (better for large templates):

For large templates, you can use $templateCache . First you add a template:

 myApp.run(function($templateCache) { $templateCache.put('myDirective.html', '<button>Fire callback</button>'); }); 

Then use it conditionally, as option 1, but with $templateCache.get() :

 link: function (scope, element, attrs) { if (attrs.callbackExpression) { var html = $templateCache.get('myDirective.html'); element.replaceWith(html); } } 

Be sure to enter $templateCache in your directive:

 myApp.directive('myDirective', function ($templateCache) { 

Here's a demo using $templateCache : http://jsfiddle.net/ZC4MZ/3/

Option using only a template:

To use a template, you need a variable in the scope. To do this, you can save everything as you have, just add:

 link: function(scope, element, attrs) { scope.callbackExpression = attrs.callbackExpression;} } 

Demo version of the template / area: http://jsfiddle.net/ZC4MZ/5/

+3
source

You can use the $ attrs object, which you can enter in yours to get this information.

Markup:

  <body ng-app="myApp" ng-controller="MyController"> <my-directive text="No Expression"></my-Directive> <my-directive text="Expression" callback-expression="myCallback()"></my-Directive> </body> 

JS:

 app.directive('myDirective', function(){ return { restrict: "E", scope: { text: '@', callbackExpression:'&' }, templateUrl: "partial.html", link: function($scope, $elem, $attrs) { $scope.expressionCalled = false; if ($attrs.callbackExpression) { $scope.expressionCalled = true; } } } }); 

I created a desktop for this example: http://plnkr.co/edit/K6HiT2?p=preview

+1
source

Source: https://habr.com/ru/post/958025/


All Articles