Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
8
rated 0 times [  12] [ 4]  / answers: 1 / hits: 100953  / 12 Years ago, thu, february 14, 2013, 12:00:00

I have a directive that has its own controller. See the below code:



var popdown = angular.module('xModules',[]);

popdown.directive('popdown', function () {
var PopdownController = function ($scope) {
this.scope = $scope;
}

PopdownController.prototype = {
show:function (message, type) {
this.scope.message = message;
this.scope.type = type;
},

hide:function () {
this.scope.message = '';
this.scope.type = '';
}
}

var linkFn = function (scope, lElement, attrs, controller) {

};

return {
controller: PopdownController,
link: linkFn,
replace: true,
templateUrl: './partials/modules/popdown.html'
}

});


This is meant to be a notification system for errors/notifications/warnings. What I want to do is from another controller (not a directive one) to call the function show on this controller. And when I do that, I would also want my link function to detect that some properties changed and perform some animations.



Here is some code to exemplify what I'm asking for:



var app = angular.module('app', ['RestService']);

app.controller('IndexController', function($scope, RestService) {
var result = RestService.query();

if(result.error) {
popdown.notify(error.message, 'error');
}
});


So when calling show on the popdown directive controller, the link function should also be triggered and perform an animation. How could I achieve that?


More From » jquery

 Answers
101

This is an interesting question, and I started thinking about how I would implement something like this.



I came up with this (fiddle);



Basically, instead of trying to call a directive from a controller, I created a module to house all the popdown logic:



var PopdownModule = angular.module('Popdown', []);


I put two things in the module, a factory for the API which can be injected anywhere, and the directive for defining the behavior of the actual popdown element:



The factory just defines a couple of functions success and error and keeps track of a couple of variables:



PopdownModule.factory('PopdownAPI', function() {
return {
status: null,
message: null,
success: function(msg) {
this.status = 'success';
this.message = msg;
},
error: function(msg) {
this.status = 'error';
this.message = msg;
},
clear: function() {
this.status = null;
this.message = null;
}
}
});


The directive gets the API injected into its controller, and watches the api for changes (I'm using bootstrap css for convenience):



PopdownModule.directive('popdown', function() {
return {
restrict: 'E',
scope: {},
replace: true,
controller: function($scope, PopdownAPI) {
$scope.show = false;
$scope.api = PopdownAPI;

$scope.$watch('api.status', toggledisplay)
$scope.$watch('api.message', toggledisplay)

$scope.hide = function() {
$scope.show = false;
$scope.api.clear();
};

function toggledisplay() {
$scope.show = !!($scope.api.status && $scope.api.message);
}
},
template: '<div class=alert alert-{{api.status}} ng-show=show>' +
' <button type=button class=close ng-click=hide()>&times;</button>' +
' {{api.message}}' +
'</div>'
}
})


Then I define an app module that depends on Popdown:



var app = angular.module('app', ['Popdown']);

app.controller('main', function($scope, PopdownAPI) {
$scope.success = function(msg) { PopdownAPI.success(msg); }
$scope.error = function(msg) { PopdownAPI.error(msg); }
});


And the HTML looks like:



<html ng-app=app>
<body ng-controller=main>
<popdown></popdown>
<a class=btn ng-click=success('I am a success!')>Succeed</a>
<a class=btn ng-click=error('Alas, I am a failure!')>Fail</a>
</body>
</html>


I'm not sure if it's completely ideal, but it seemed like a reasonable way to set up communication with a global-ish popdown directive.



Again, for reference, the fiddle.


[#80216] Wednesday, February 13, 2013, 12 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
ellisw

Total Points: 625
Total Questions: 92
Total Answers: 88

Location: Kazakhstan
Member since Mon, Sep 26, 2022
2 Years ago
ellisw questions
Mon, Aug 23, 21, 00:00, 3 Years ago
Fri, Nov 20, 20, 00:00, 4 Years ago
Sat, Jun 20, 20, 00:00, 4 Years ago
Tue, Apr 21, 20, 00:00, 4 Years ago
;