Famous / famous-angular

Bring structure to your Famo.us apps with the power of AngularJS. Famo.us/Angular integrates seamlessly with existing Angular and Famo.us apps.
https://famo.us/angular
Mozilla Public License 2.0
1.92k stars 275 forks source link

Is it possible to use Draggable? #168

Closed janober closed 10 years ago

janober commented 10 years ago

Did not find anything about it in the docs. Also did not find anything about any of the other modifiers except "Modifier" itself. How can it be used? Thanks!

btw. is this the preferred way to ask questions or is there somewhere a forum I do not know about?

zackbrown commented 10 years ago

Hey @janober, for now this is a fine place to ask questions specific to Famo.us/Angular.

EDIT: There is now an fa-draggable directive available Currently, only the vanilla Modifier has a declarative fa- wrapper.

EDIT: THIS APPROACH IS INCORRECT. Use fa-draggable to use Draggable.

A simple solution for now would be to use $famous.find('.your-selector') inside a directive post-link to dig out the renderNode that you want to attach Draggable to, then create your Draggable in vanilla Famo.us and .add() it to that renderNode.

We should also implement an fa-draggable directive so you don't have to do that—I'll add it to the tracker.

janober commented 10 years ago

Great, thanks a lot for your help. Will give that a try!

janober commented 10 years ago

Are you sure that it is possible like that? Because I do not get it working.

I do something like that: var surfaces = $famous.find('.whatever'); surface = surfaces[0]; var draggable = new Draggable(); console.log( surface.renderNode ); // It outputs it and it is actually there surface.renderNode.add(draggable);

But all I get then is: Uncaught TypeError: undefined is not a function

zackbrown commented 10 years ago

That snippet is really close: you can't add a Modifier directly to a Surface; a Modifier only affects elements below it in the render tree, and a Surface is strictly a leaf node of the render tree (there's nothing else beneath it—this is why there's no .add function available on Surface.) This is a counter-intuitive concept and Melody (@arayi) from Famo.us recently wrote a good blog post about it: http://famo.us/blog/modifiers-affect-subtrees/

EDIT: THIS APPROACH IS INCORRECT. Use fa-draggable to use Draggable.

So you could try adding a <fa-view class="whatever"> above your fa-surface and .adding Draggable to that.

Does that work?

janober commented 10 years ago

Ah totally forgot about that.

I now added the view between modifier and surface and call the following code: var views = $famous.find('.whatever'); var view = views[0]; var surface = view.children[0]; var draggable = new Draggable(); draggable.subscribe(surface.renderNode); view.renderNode.add(draggable);

It apparently attaches now fine (at least no error messages) but the nodes are still not draggable. What could still be wrong then? Thanks!

zackbrown commented 10 years ago

Ah you know what, I gave you some bad advice. These two blocks of code are not equivalent:

//this one works
myNode.add(myModifier).add(mySecondNode);

vs

//this one doesn't
myNode.add(mySecondNode);
myNode.add(myModifier);

And the approach I was suggesting with $famous.find is effectively the second one—I'm sorry to lead you down a wrong path there.

So in contrition, I went ahead and threw together fa-draggable and it's available on master. https://github.com/Famous/famous-angular/commit/a11c12dc927225ca0b1a4b1b0b4187760c08fe5a Note that since you need to pipe to the draggable's sync to get it to work, you'll need to add a fa-pipe-from on the fa-draggable, pass that attribute a reference to an EventHandler, and then pipe to that EventHandler from a fa-surface inside of it. See the example template and controller in famous-angular-examples: https://github.com/thomasstreet/famous-angular-examples/blob/master/app/scripts/controllers/draggable.js and https://github.com/thomasstreet/famous-angular-examples/blob/master/app/views/draggable.html

janober commented 10 years ago

You are amazing! Thanks for adding the draggable for me! Really great and appreciated!

However have to confess that I was still not able to get it working. Updated to new version, added everything like described but even then the surface is not "draggable" for me. So I then downloaded the "famous-angular-examples" to test that but also that did sadly not work for me. Tested it in both Firefox and Chromium. Does the example work for you? Just to be sure I tested again the vanilla-famous draggable example and that did run fine for me.

Sorry for causing that much work...

zackbrown commented 10 years ago

It does work for me, and I just tried a fresh clone to be sure—my best guess as to the issue would be that the fa-draggable directive is not available in 0.3.0 but is instead only available on master right now. If you tried just doing a bower update or pulling down specifically 0.3.0, that could explain why it isn't working.

Easiest thing to do to make sure you're on master (assuming you're using bower and it's installing into bower_components) would be to:

# cd into the root of your app
rm -rf bower_components/famous*
bower cache clean
bower install  https://github.com/Famous/famous-angular.git#master

That should pull down the lib off of master. As long as you've already made the switch to famous-global with 0.3.0 [i.e. updating your index.html to remove requirejs stuff and include famous-global.js,] that should do the trick for you. You could try these steps in the famous-angular-examples repo that you already cloned to test it out.

janober commented 10 years ago

Great thanks! Yes that is what I did (pulled down 0.3.0 specifically). Did run the above code and now the example works perfectly. Sorry I am still new to JavaScript, Angular, famo.us and bower. So still much to learn! ;-)

Thanks a lot for all your help and great work combining famous & angular! So then I finally close this.