Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple ngDroplet instnaces on same page #49

Open
zjda opened this issue Feb 22, 2016 · 20 comments
Open

Multiple ngDroplet instnaces on same page #49

zjda opened this issue Feb 22, 2016 · 20 comments

Comments

@zjda
Copy link

zjda commented Feb 22, 2016

Hi, I wrote a directive with isolated scope to wrap ngDroplet. When I put 2 instances of my directive in a page, both of them receive '$dropletFileAdded' event if a file is added to one of them. Based on the 2 parameters passed in the handler (p1 and p2), I cannot figure our how to update my model. The test files are attached.

The problem can be solved by either including target field information or limiting the event in the $scope. Any idea will be appreciated.

-ZJ

test.zip

@SmailHammour
Copy link

I have the same problem and i have no idea how to fix this.

@Wildhoney
Copy link
Owner

I've added the ability to define the callbacks via attributes — which I think will help you folks differentiate between which Droplet directive is making those calls.

<droplet ng-model="interface" on-add="onAdd(file)" />

I don't have time to document the changes at the moment, but if you look at the scope then you'll see there are 4 bindings. Then take a look at the actual call to see which arguments are passed 👍

I've incremented the patch version, as this shouldn't be a breaking change. Using the attributes on the directive are optional — and until we test this further — and add a couple of unit tests — we'll stick with the $broadcast approach.

Could you guys give it a test and see if this fixes what you're trying to achieve, please?

@zjda
Copy link
Author

zjda commented Feb 24, 2016

Thank you so much for your quick update. After I refreshed my workspace with the your latest code, magic happened: only target directive received "$dropletFileAdded" event. In the other word, if I add a file in the first droplet, only the first one receives the event but the second does not. I thought you did not change the $broadcast, so I have gone back and forth with the old version and the new version of ngDroplet to ensure the $broadcast behavior changed. The new attribute "onAdd" is also working for me.

@SmailHammour
Copy link

@zjda care to share how you implemented this please?

@Wildhoney
Copy link
Owner

In my haste this morning, I accidentally broke the backwards compatibility and so have released v0.5.14 and deprecated v0.5.13 on npm — please ignore the $broadcast behaviour, as that will function as it always has.

@Smiley01987 try something like below, where the function — onAdd — on your controller/directive could change depending on the Droplet instance you're currently handling.

<droplet ng-model="interface" on-add="onAdd(file)" />

Is the attribute approach fit for purpose? Please advise on any other changes you folks would be looking at to satisfy your implementation 👍

@Wildhoney
Copy link
Owner

We have:

<droplet on-add="add(file)" on-delete="remove(file)" on-success="success(response, files)" on-error="error(response)" />

@zjda
Copy link
Author

zjda commented Feb 24, 2016

@Wildhoney: Basically you are going to have attributes mirroring your broadcast events. If so, you may want to add on-ready to the attribute, which will be used to set allowedExtensions and other settings for each individual droplet in a page. For example, I may have one droplet for photo and another one for pdf/word resume.

@Smiley01987: as Wildhoney mentioned, you just need to add the attribute and have your hander in your controller. For example, if you have 2 droplets on you page, you can have

<droplet ng-model="interface1" on-add="onAdd1(file)" /> <droplet ng-model="interface2" on-add="onAdd2(file)" />

In you controller, you can have 2 functions

$scope.onAdd1 = function(file) {...} to do whatever you want when a file is added to the first droplet, and $scope.onAdd2 = function(file) {...} for the second droplet. Or you can develop your own directive to wrap droplet.

Thanks,
-ZJ

Wildhoney added a commit that referenced this issue Feb 24, 2016
@Wildhoney
Copy link
Owner

@zjda 👍 Added onLoad. Thanks.

I don't intend to keep both approaches, but will see how well the attribute functions are taken and may remove the $broadcasts in future.

@zjda
Copy link
Author

zjda commented Feb 25, 2016

I have tested on-add, on-delete, and on-load:

<droplet ng-model="interface" on-add="added(file)" on-delete="removed(file)" on-load="loaded()" class="droplet">...`

and they work perfectly for me. Since I have my own upload method, I am not able to test on-success and on-error.

Again, thank you very much for the update.
image

@Wildhoney
Copy link
Owner

No problem!

Small consideration: do you think we're better off with hyphens in the attribute names (on-add) — which I prefer for readability — or without — and thus sticking closer to the HTML convention (onadd).

@Smiley01987 Did you have any luck with the attribute approach?

It's also worth pointing out that you can pass through additional arguments to those callbacks — which will also help if you have a dynamic list of droplets.

<droplet on-add="added(file, 'first')" ng-model="firstInterface" />
<droplet on-add="added(file, 'second')" ng-model="secondInterface" />

@zjda
Copy link
Author

zjda commented Feb 25, 2016

I agree with you. The following looks better

<droplet on-add="added(file, 'first')" ng-model="firstInterface" />

than

<droplet onadd="added(file, 'first')" ng-model="firstInterface" />

@SmailHammour
Copy link

@Wildhoney sadly it still doesnt work for me. The function doesn't get called when adding a file to the droplet.

Here is my code:

Archive.zip

@Wildhoney
Copy link
Owner

@Smiley01987 Where do you add the <droplet /> node to your directive? Is that in game-images.html? If that's the case then in there change it to <droplet on-add="added(file)" />ngDroplet will then invoke the added function in the given scope context.

@SmailHammour
Copy link

@Wildhoney Yes exactly, in game-image.html. I added my code in my previous post.

@Wildhoney
Copy link
Owner

@Smiley01987 I've set you up a JSFiddle which illustrates how to achieve this through the attributes. Please let me know if this doesn't make things clearer.

@SmailHammour
Copy link

@Wildhoney I tried your code and everything works fine, but as soon as I change the droplet element to droplet-upload-multiple with an ng-model it fails.

@SmailHammour
Copy link

@Wildhoney I moved everything out of the directive and into the HTML file. I also added the $scope function in my main controller but still nothing.

HTML:
<droplet-upload-multiple on-loaded="loadedWinnerImages(winnerImages)" on-add="addedWinnerImage(file)" ng-model="winnerImages" id="winnerImages" name="winnerImages"></droplet-upload-multiple>

Scope functions:

$scope.addedWinnerImage = function(file){ console.log('Added: ' + file.file.name); }; $scope.loadedWinnerImages = function() { console.log('Loaded!'); };

@zjda
Copy link
Author

zjda commented Feb 26, 2016

@Smiley01987 The attributes should be used for <droplet> NOT for <droplet-upload-multiple> or <droplet-upload-single>:

<droplet ng-model="interface" on-add="added(file)" on-delete="removed(file)" on-load="loaded()" class="droplet">

@Wildhoney
Copy link
Owner

@zjda is right. I've updated the JSFiddle to show you how to tie the two directives together — droplet and droplet-upload-single.

@SmailHammour
Copy link

@Wildhoney & @zjda, thanks a lot guys. Now it works perfectly!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants