I'm trying to use a jQuery plugin (Plupload) with AngularJS. I have created a directive that will be my file upload "widget". The directive looks like this (The code in the link function is a very simplified version of the example on the Plupload site):
.directive('myFileUpload', function () {
return {
restrict: 'E',
replace: true,
link: function(scope, element, attrs) {
scope.uploaderProperties = {
runtimes : 'html5,flash,html4',
url : 'media/upload',
max_file_size : '10mb',
container: 'fileUploadContainer',
drop_element: 'fileUploadDropArea'
};
scope.uploader = new plupload.Uploader(scope.uploaderProperties);
scope.uploader.init();
scope.uploader.bind('FilesAdded', function(up, files) {
scope.$apply();
});
},
templateUrl: 'upload.html'
};
});
My upload.html file looks like this:
<div id="{{uploaderProperties.container}}">
<div id="{{uploaderProperties.drop_element}}" style="border: 1px black dashed;">Drop files here<br><br><br></div>
Files to upload:<br>
<div ng-repeat="currFile in uploader.files">{{currFile.name}} ({{currFile.size}}) </div>
<br><br>
<!-- for debugging -->
{{uploader.files}}
<br><br>
</div>
When I include the directive on my page with a <my-file-upload> element, all the data bindings happen correctly. The problem is, when scope.uploader.init(); runs, the ids haven't been inserted into the DOM yet, and so Plupload complains and breaks since it can't select those elements. If I just hard-code the fileUploadContainer and fileUploadDropArea ids in the template, it works just fine. However, I'd really like to define those ids in only one place.
So, is there any way I can run the init() on the uploader after the template is linked in? I thought about using $timeout to delay when it runs, but that seems like a pretty big hack to me. Is there a more correct way of accomplishing this?
UPDATE
I wrapped the init() in a $timeout like this
$timeout(function() {
scope.uploader.init();
}, 2000);
just to make sure it would behave the way I was thinking, and sure enough, with this delay the plugin gets set up correctly and works. However, I do not want to have to rely on the timing of the $timeout. If there was just some way I could call scope.uploader.init(); after the template is linked in, everything should work fine. Anyone know of a good way of doing this?