I'm new to AngularJS and this is my first attempt in creating a custom directive. I found that the same piece of code for downloading a file was used in multiple places so I want to create a directive to improve modularity. Here's is my first attempt.
angular.module('defaultModule')
.directive('downloadFile', function () {
return {
restrict: 'A',
scope: true,
//scope: {
// fileURL: '@',
// fileName: '@',
//},
link: function (scope, element, attrs) {
function startDownload() {
console.log('scope.fileURL', 'scope.fileName'); // gives undefined values in isolated scope
const link = document.createElement('a');
link.setAttribute('target', '_blank');
link.setAttribute('href', scope.fileURL);
link.setAttribute('download', scope.fileName);
document.body.appendChild(link);
link.click();
link.remove();
console.log("download completed!");
}
element.on('click', startDownload);
}
};
});
and I use it like this in my html code
<!-- {{fileURL}} and {{fileName}} are defined -->
<button download-file type="button">Download</button>
I have a few questions regarding this implementation:
- As you can see now, I'm currently using the inherited scope and it works fine, I tried to switch to isolated scope (which is commented out below the scope) because I heard it was the best practice. However, it seems that both fileURL and fileName have undefined values when I use the isolated scope. I do not know a proper way to call them in my link function.
- For the link function, I've researched what element and attrs refer to, but most examples are for directives restricted to 'E'. If I want to use the directive as an attribute only, does element refer to the tag in which the directive is used, in that case what will attrs be?
- In term of separation of concerns, is this link function well written? It solves the problem but it does try to manipulate the DOM instead of just setting it up. Would it be better if I use a controller instead?
Many thanks in advance!