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 276 forks source link

Feature Req: fa-edge-swapper #199

Closed bguiz closed 9 years ago

bguiz commented 9 years ago

Famo.us has an edge swapper view: https://famo.us/docs/views/EdgeSwapper

Example app: https://github.com/Famous/examples/blob/master/src/examples/views/EdgeSwapper/example.js

Can we get an fa-edge-swapper element directive in famous-angular?

Further to this, it would be great if the directive provided a means for the angular router - be it $routeProvider or $stateProvider to trigger the EdgeSwapper.show() on the new view to be shown.

Nytrm commented 9 years ago

EdgeSwapper only shows and hides a single view if i am correct.

You will probably be showing and hiding these views inside the controller. Why not make a RenderNode and add a EdgeSwapper to the node ?

Template:

 <fa-render-node fa-node="edgeSwapper" id="edgeSwapper"></fa-render-node>

Scope:

$scope.edgeSwapper = new EdgeSwapper();
$scope.edgeSwapper.show(someSurface)
bguiz commented 9 years ago

@Nytrm yes, of course you can do that... Following this logic, most of the directive provided by famous-angular are strictly not necessary, as one can use render node for many of them. But that is missing the point of famous-angular, which is to be able to declaratively specify the scene graph within the templates.

Nytrm commented 9 years ago

@bguiz I understand, Maybe when i have some time left i create a directive for this view.

<fa-edge-swapper>
    <fa-surface>Surface One</fa-surface>
</fa-edge-swapper>

Would you like the template to parse that and hide/show different content from the controller.

<fa-edge-swapper>
    <fa-surface>Surface One</fa-surface>
    <fa-surface>Surface Two</fa-surface>
    <fa-surface>Surface Three</fa-surface>
</fa-edge-swapper>

Or to be able to add multiple surfaces to the template like this?

zackbrown commented 9 years ago

EdgeSwapper supports showing many different render subtrees, but only one at a time. E.g. you can .show() one View, and then .show() another, similarly to LightBox.

The reason we haven't yet implemented EdgeSwapper, LightBox and co. is exactly because of this 0-to-n children behavior. The only semi-elegant purely HTML APIs I could think of to support them would be either one that requires passing selectors (most likely classes or IDs) for which elements to show/hide, or one that requires passing indexes to achieve the same. Neither of these feel right to me, though.

Really, a better API would be something like ui-router, where you configure the n different supported templates with Javascript. Indeed, why recreate a ui-router-style API when we could use the exact one instead? I've been thinking the best way we could support EdgeSwapper, LightBox, Deck, and RenderController would be to support them as directives on top of a <ui-view>. Something like <ui-view fa-edge-swapper></ui-view> — the fa-edge-swapper directive would cause edgeSwapper's .show() function to be called on the various subtrees that are loaded as ui-views. This could be done by patching into ngAnimate similarly to how fa-animate-enter and fa-animate-leave work (or really, probably by using the exact underlying logic.)

By patching into ngAnimate, we should also be able to support EdgeSwapper, LightBox, etc. on top of anything that has enter or leave events, like ng-repeated elements or anything with ng-if. I don't think these would be quite as elegant as ui-views, but there would probably be reasons and ways to make them work.

Nytrm commented 9 years ago

I like the idea to support them as directives on top op the :+1:

bguiz commented 9 years ago

@zackbrown That sounds like a good idea, however, worth considering is that this will introduce a dependency between famous-angular and ui-router. Not everyone will want or need to include ui-router in their famous-angular apps.

I would thus say an elegant solution would be to support <fa-edge-swapper> with, instead of requiring elements to be nested directly, have something akin to the ngInclude directive, where you specify the name of a HTML fragment, available at the base level.

If it detects that it is within a <ui-view>, it should support what you have described above.

These are, of course, just ideas. I'm throwing them out there - not sure whether implementing these is feasible.

zackbrown commented 9 years ago

To clarify, the approach I proposed above doesn't introduce a programmatic dependency on ui-router. The transitions would be based solely on ngAnimate events, so ui-router would be an excellent but not required way to use EdgeSwapper & co.

That's a great idea with ngInclude—in fact, this ngAnimate-hooked approach should work out of the box on top of ngInclude, since ngInclude fires enter and leave events upon src changes. So <ng-include src="template.url" fa-edge-swapper></ng-include> would work just as well as <ui-view fa-edge-swapper></ui-view>

ghaiat commented 9 years ago

+1 :)

bguiz commented 9 years ago

To clarify, the approach I proposed above doesn't introduce a programmatic dependency on ui-router.

That sounds great!

So would work just as well as

So the way to use this would be: <ng-include src="{{viewName}}" fa-edge-swapper></ng-include> and setting viewName as a property on $scope. When the value of viewName is changed, this triggers faEdgeSwapper to change the template within the ngInclude directive. Am I understanding this correctly?

zackbrown commented 9 years ago

Yes, that would be the goal! Implementing this will be a little bit tricky, as I think we'll need to refactor a bit of the $famousAnimate code, which is one of the more complex parts of the codebase. I'll take a look right now.

zackbrown commented 9 years ago

Okay, the $famousAnimate refactor is complete, seems stable, and tests are passing a7e041a1286cb3cc3068264b53554b53f1613d47 9007a8e536f20aea707ad2e391b50e501314fd8c 5a2958206168c897a46a391d0077ff93215fdb6b and 76eacd67775176ca0f22cbddd54e06acb56344a5; gonna take a stab at fa-edge-swapper.

zackbrown commented 9 years ago

Good golly, that was a dive into the depths of the ngAnimate <=> Famo.us/Angular interface. But done! 5ec551327f44f1d6188860d816b247b149f9a9cd

No unit tests yet, but works per my working example in famous-angular-examples.

The api is: <element-that-will-fire-enter-and-leave-events fa-edge-swapper></element-that-will-fire-enter-and-leave-events>. Supports <ui-view>, <ng-include> and probably <ng-view>. Seems to work well, but please report if anyone runs into any issues.

RenderController, LightBox, and friends will be much easier to implement now that the supporting refactors are in place throughout the lib.

bguiz commented 9 years ago

Thanks!