Reputation: 1353
I have a directive for uploading files. I am calling this in my view called "UploadRecords.html". I have a button called "Upload" in "UploadRecords.html". On click of this button, I want to call the "UploadAll" method defined inside the link function in my directive. What are the ways to achieve this.
Basically I want to call a directive function on click of a root scope element.
Note: I am using isolated scope in my directive
angular.module('fileUpload', [])
.directive(
"fileUpload",
function () {
return ({
restrict: 'E',
scope: {
onSuccess: '&',
onError: '&',
},
templateUrl: 'Templates/FileUploadTemplate.html',
link: function (scope, element, attrs) {
scope.files = [];
scope.addFile = function (element, documentType) {
if (element.files.length > 0) {
$.each(element.files, function (index, file) {
scope.files.push(file);
});
}
scope.$apply();
}
scope.uploadAll = function () {
//This is where I upload the files to the web api using a FormData post
}
}
});
}
);
<file-upload on-success="onFileUloadAllSuccess()" on-error="onFileUloadAllError()"></file-upload>
<button type="button" class="btn btn-default">Upload All</button>
Thanks, Sam.
Upvotes: 1
Views: 276
Reputation: 270
Broadcast can be in my opinion a good solution to your problem
You can do something like that :
Root Controller -> Directive
Root Controller
$scope.$broadcast('go');
Directive
$scope.$on('go', function () { alert('event is clicked') });
Directive -> Root Controller
Root Controller :
$scope.$on('go', function () { alert('event is clicked') });
Directive :
$scope.$emit('go');
** This is not necessarily the most elegant solution, that we agree but it will solve your problem
Upvotes: 1
Reputation: 36189
The way you have setup your HTML, there is no way for your button to communicate with your directive, since they are completely separate. You have a few options:
Move the button inside the FileUploadTemplate.html so that it is now under the directive's scope. If you do so, all you have to do is add ng-click="uploadAll()"
to the attribute:
Upload All
Define a directive for your button. Then use $emit
to communicate between the two directive.
Define a directive for your button. Define a "parent" directive that has the two children, button and your current template. This way ,the scope inside the parent is accessible to both children, and they can communicate via the parent.
Here is how you can use $emit
. Define your button html as:
<button type="button" class="btn btn-default" ng-click="uploadAll()" button-upload>
Upload All
</button>
Now add a directive for this:
app.directive('buttonUpload', ['$rootScope',
function($rootScope)
{
return {
restrict: 'A',
link: function(scope, element, attrs)
{
scope.uploadAll = function() {
$rootScope.$emit('UPLOAD_ALL');
}
}
}
}
]);
Then in your fileUpload
directive, you can have:
app.directive('fileUpload', ['$rootScope',
function($rootScope)
{
return {
// Your restrict, templateUrl, scope
link: function(scope, element, attrs)
{
// All your other code
// remove scope.uploadAll
// This will get called everytime $emit is broadcasted
$rootScope.$on('UPLOAD_ALL', function(event) {
// Your upload code goes here
});
}
}
}
]);
This is NOT a really good approach: you shouldn't really use $emit
and $broadcast
. You should consider my third option of having a parent of the two directive.
Upvotes: 2