Escolar Documentos
Profissional Documentos
Cultura Documentos
One of the original goals of the Ionic Framework was to encourage custom mobile UI development with HTML5,
building UIs that were innovative, interactive, and fun, but weren't necessarily part of the core mobile UI
framework on a given platform.
We've seen native developers doing this for some time. Startups and companies like Jelly, Path, Facebook, and
Google have very custom mobile UIs filled with animations, lots of interesting gesture-based interactions, and
other unique effects. This helps create a potentially more fluid experience for the user performing an app-specific
task, but also serves as a way to make a design impact and draw more attention to the app itself.
I was playing with the Jelly app last week and fell in love with the swipeable card UI. I felt it was fun and
effective enough that tons of mobile developers would want to emulate it for their apps, much like the draggable
Side Menu made popular by Path and Facebook:
But to build this UI, it would have to be done from scratch, seeing as it's not a built in component in UI
frameworks available in any mobile SDKs. So, I spent a nice Saturday building a reusable Ionic and AngularJS
based card layout (demo and code here) and I want to show you how I did it and how you can build your own
Ionic components, too!
A perfect example of a View Controller is a Tab Bar Controller with three tabs and three pages. This controller
has to manage the three sub pages (which can be View Controllers on their own), as well as the Tab Bar which
manages its child Tab Items.
Mobile SDKs often come with several built-in Views and View Controllers. For example, iOS has the
UITabBarController, UINavigationController, UITableViewController, and a few others, and uses Tab Bars,
Buttons, and List items extensively. Most common mobile UIs can be built with just these core controllers and
views.
But when we want to create any non-standard UI, we need to build our own View Controllers and possibly Views
to make this work. And we shouldn't be afraid to, it's exactly how the pros do it!
With the background about View Controllers out of the way, let's look at the final UI we are going to build (play
the video demo):
Card stack
To start, we need to look at this UI as a stack of cards that the user can swipe between. This means we need some
sort of View Controller that manages the card stack, popping ones off the stack that are swiped, and letting the
user push new ones onto the stack. Let's call this theSwipeableCardController:
pushCard: function(card) {
this.cards.push(card);
// Show the card
},
popCard: function() {
var card = this.cards.pop();
// Animate the card out
}
})
That's pretty much the core of this View Controller. Apart from managing the stack, the controller will also
initialize new cards and tell the cards to animate in our out, but that's about it!
The Card View, however, is more complicated. Since the cards are rendered to the screen (as opposed to
controllers which are pure-logic), they need to keep track of their DOM element and also attach event listeners to
that element.
In the example below I've included a small snippet of what happens in the drag event, but the full example is in
the repo:
ionic.onGesture('dragstart', function(e) {
// Process start of drag
}, this.el);
ionic.onGesture('drag', function(e) {
// Process drag
window.rAF(function() {
self._doDrag(e);
});
}, this.el);
ionic.onGesture('dragend', function(e) {
// Process end of drag
}, this.el);
},
_doDrag: function(e) {
// Calculate how far we've dragged, with a slow-down effect
var o = e.gesture.deltaY / 3;
The gesture system will also tell us how far we've dragged (e.gesture.deltaY in the example above), and can also
compute the velocity or rotation of the drag (useful for gestures that "throw" a view around).
If we just had the above View and View Controller, we'd have to manage it all in Javascript. We'd create a few
DOM nodes to display each card, instantiate a few SwipeableCardView's for those nodes, put them in a
new SwipeableCardController and let the magic happen.
But that's annoying to have to code that by hand, and we miss out on using AngularJS to integrate this card stack
with our scope data. For that we need to build some custom directives. But first, let's assume we want the
directive markup to look like this:
<swipe-cards>
<swipe-card ng-repeat="card in cards" on-destroy="cardDestroyed($index)" on-swipe="cardSwiped($index)">
<!-- Card content here -->
</swipe-card>
</swipe-cards>
We use a custom element directive to specify that this entire directive will be powered by
our SwipeableCardController, with each child<swipe-card> being an instance of our SwipeableCardView.
// We can push a new card onto the controller card stack, animating it in
swipeCards.pushCard(swipeableCard);
}
}
}
}])
I love the simplicity of wrapping a complicated UI like the Swipeable Cards into a set of tiny AngularJS
directives that play nicely with the rest of your Angular app. In fact, this is how most of the controllers and views
are exposed in the Ionic code base.
One question we receive a lot is why we decided to use element directives instead of attribute or class name
directives. Perhaps the biggest reason is because we believe element directives should be used when
specifying components, and attributes or classes used to specifybehavior. As browsers evolve and features such
as Web Componentsare widely available, this will become the prodominant way of building reusable components
for the web.
If you are new to writing custom AngularJS directives, hopefully it's illuminating to see a real one in the wild!
Conclusion
The point of this article is to show you the process behind creating new, innovative mobile UIs from the ground
up, using Ionic utilities where possible. But one takeaway should be that no framework will have every UI built
in for you, and you should be open to creating new components in the spirit of the framework you choose to
develop with.