In my opinion, one of the main reasons to use a controller to add behavior to a directive (instead of the linking function) is, that you cannot really unit test the logic in a directive's link function (whereas controllers can easily be tested and mocked).
Since the controller is injected into the directive's linking function you can easily call (or init) some methods in the controller with the actual element to bind behavior to it.
For example:
angular.module('foo', [])
.controller('MyController', function () {
this.init = function (element) {
element.on('click', function () {
//do something
});
};
})
.directive('MyDirective', function () {
return {
controller: 'MyController',
link: function (scope, elem, attrs, ctrl) {
ctrl.init(elem);
}
};
});
If you're just adding some scope variables that should be displayed in the directive's template (i.e. nothing that's really crucial to be tested) - a linking function is just fine.
The guys at angular-ui-bootstrap are doing good example of doing it that way: https://github.com/angular-ui/bootstrap/tree/master/src