Sei sulla pagina 1di 40

Angular + Django

A match made in heaven

github.com/nnja/tweeter

Django Templates
are not my favorite

Need to refresh the page to submit a form


Tough to write JS around template tags
Difficult to Unit Test
Template tags can be hard to grok for front
end devs

also end tags are annoying

Forms get complex, fast.

Why Endpoints are Better (IMHO)


Faster - no waiting for a page to reload
Swap frameworks - Ability to use any javascript
framework, and switch them out easily.
Reusable - Have a mobile app? Your backend is
already done!

Dogfooding
If your endpoints are public, you can eat your own
dogfood by consuming them internally.

REST Frameworks are Standard


Front End Devs know how to use them.

AngularJS
MVC - Responsibilities are separated
Single page app. That means no refreshes for new
content, and a better user experience
Scope - Variables are bound between JS & View no nasty JQuery
Easily Unit Tested

The bad
You have to use Javascript

If you dont like it...

Use another framework


Excellent presentation on choosing a JS Framework
http://brianholt.me/

Lets build a Tweeter


http://github.com/nnja/tweeter

Requirements
1. Display a list of tweets from all Users
2. Display my tweets (logged in User)
3. Show my profile - username, etc.

Our endpoints are created w/ DRF


Django Rest Framework
- Easily create a REST endpoint for your application.

Our Model
class Tweet(models.Model):
user = models.ForeignKey(User)
text = models.CharField(max_length=140)
timestamp = models.DateTimeField(auto_now_add=True)

class Meta:
ordering = ['-timestamp']

Our endpoints
/api/users/
/api/tweets/
/api/users/:id
/api/tweets/:id

GET /api/tweets/
HTTP 200 OK
Vary: Accept
Content-Type: text/html; charset=utf-8
Allow: GET, POST, HEAD, OPTIONS
[
{
"text": "Bob is the coolest name EVAR",
"user": "bob",
"timestamp": "2014-08-29T18:51:19Z"
}
]

Configuring Angular

Step 1.
Include angular.js
Throw ng-app into one of your tags.
Everything within those tags is now an angular
app.
<html lang="en" ng-app="tweeterApp">

{{ }}
UH OH
Angular tags and Django template tags conflict.

Tell angular to use different tags


I like [[ this ]]
or use
{% verbatim %} {% endverbatim %}

static/js/app.js
$interpolateProvider.startSymbol('[[').endSymbol(']]');

$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';

$resourceProvider.defaults.stripTrailingSlashes = false;

Angular Resources
A wrapper around a REST Endpoint at a location.
angular.module('tweeterApp.services', ['ngResource'])
.factory('Tweet', function($resource) {
return $resource('/api/tweets/:id/');
});

Default Actions
{ 'get':

{method:'GET'},

'save':

{method:'POST'},

'query':

{method:'GET', isArray:true},

'remove': {method:'DELETE'},
'delete': {method:'DELETE'} };

Creating a new object


var newTeet = new Tweet();
newTweet.name = "Look, a tweet!";
newTweet.$save();

Callbacks
Tweet.get({id:123}, function(tweet){
console.log(tweet);
});

VS Promises
Tweet.get({id:123})
.$promise.then(function(tweet) {
$scope.tweet = tweet;
});

Scope
You change a value in the controller, and its
automagically updated in the view.
And vice versa.

Angular Controllers
tweeterControllers.controller('TweetCtrl', function
TweetCtrl($scope, Tweet) {
...
});

The meat
Tweet.query(function(response) {
$scope.tweets = response;
});

$scope.submitTweet = function(text) {
var tweet = new Tweet({text: text});
tweet.$save(function(){
$scope.tweets.unshift(tweet);
})
}

Cant get rid of all the templates


Used to pass information from django-land to
angular.
Gives us our static URL so we can load assets
(css/js)

Interacting with Django Templates


<script type="text/javascript">
angular
.module('tweeterApp.services')
.factory('AuthUser', function() {
return {
id: "{{ user.id|default:''}}",
}
});
</script>

Angular UI Routing
.config(function ($stateProvider, $urlRouterProvider) {
...
$urlRouterProvider.otherwise('/');
$stateProvider
.state('tweets', {
url: '/',
templateUrl: 'static/tweeter/partials/tweet-list.html',
controller: 'TweetCtrl',
})
};

Routing in Angular
Drop this in your base template
<div ui-view></div>

Depending on the route, the correct partial will


be rendered and inserted.

Partials
Just vanilla HTML and Angular.
Keep them in an accessible static folder.

Demo time!

Bye Everybody!
github.com/nnja/tweeter

@nnja

Potrebbero piacerti anche