When it comes to calling directive functions from controllers, I follow this approach:
function myControllerFunction = function () {
$scope.highlight();
}
The highlight()
function is defined within the directive itself.
But what if there are two different directives, each with their own highlight()
function?
Is there a way to access the actual directive object instead of directly accessing the directive function through the $scope?
I would prefer a more explicit way of specifying the directive like this:
function myControllerFunction = function () {
$scope.myDirective.highlight();
}
Is such an approach possible?
If you're wondering why I need a controller to communicate with a directive, here's an example:
My controller receives an authentication pin from the user and sends it to a service. The service returns either true or false based on the validity of the pin.
In my controller function, I check the boolean return value. If it's true, I call a directive function named highlight which highlights a div in green. If it's false, I call the same function to highlight it in red.
Below is the snippet of my controller function:
$scope.keypadEnter = function () {
userService.isCodeValid($scope.code).then(function (result)
{
if (JSON.parse(result.data)) {
$scope.highlight("lime").then(function () {
$scope.code = "";
$location.path('/clockin');
});
}
else
{
$scope.highlight("red").then(function () {
$scope.resetDisplay();
$scope.code = "";
});
}
});
};
And here is the code for the highlight function in my directive:
...
link: function ($scope, $element, $attrs) {
$scope.highlight = function (color) {
var deferred = $q.defer();
$element.effect("highlight", { color: color }, 500);
$element.find("span").css('color', '#000')
.animate({ opacity: 0 }, 500, function () {
$element.find("span").css('opacity', 1).css('color', '#fff')
});
$timeout(deferred.resolve, 500);
return deferred.promise;
}
...
Following your advice, I've updated my directive code to watch for the $scope.color
variable as shown below:
angular.module('clockin').directive('grDisplay', function ($q, $timeout) {
return {
restrict: 'A',
link: function ($scope, $element, $attrs) {
$attrs.observe('color', function (color) {
var deferred = $q.defer();
$element.effect("highlight", { color: color }, 500);
$element.find("span").css('color', '#000')
.animate({ opacity: 0 }, 500, function () {
$element.find("span").css('opacity', 1).css('color', '#fff')
});
$timeout(deferred.resolve, 500);
return deferred.promise;
});
}
}
});
Finally, here's the corresponding view code:
<div data-gr-display ng-attr-color="{{ color }}" class="display"><span>{{code}}</span></div>
However, upon testing, I encountered this error message:
TypeError: object doesn't support this property or method « observe »
at link (http://localhost:18000/App/clockin/keypad/display-directive.js:6:13)
at nodeLinkFn (http://localhost:18000/Scripts/angular.js:6692:13)
...