Django - Angularjs COMBINING Frameworks
Created by:
Yftah Peled
Full stack developer @ www.roojoom.com
Check out my Roojoom profile
Angularjs INTRODUCTION
Client side JS based Framework
MVC (two way binding between view and controller)
Directives
topics:
- What gets rendered when? - TEMPLATES / UX / SEO dilemmas
-
Forms validation
- Uploading: form Vs. API
- Passing data / variables / Settings - Player
- Django - Angular 0.1
REndering
Test case:
How should we render Django models related data?
Just Angularjs?
Just Django?
Combo
PERCEIVED PERFORMANCE
OR WHAT AND WHEN DOES THE USER SEE ON SCREEN?
Just AngularJS - async database requests (but - AngularJS 1.0.8 is 80KB)
Just Django - database requests
Combo - Just like it sounds
SEO
Django
AngularJS (PhantomJS)
Combo
Templates issues
Tags clashes - {{ }}
Directives
ng-cloak / ng-hide
Filters
Loops
D.R.Y issue on combo
Tags Clash
Django solution
{% verbtim %}
Angularjs solution:
angular.module('trekpage_editor', ['ui.bootstrap', 'filters', 'ngResource', 'ui.sortable','RjResources','ValidationModule','AddPage'])
.config(function($interpolateProvider,$httpProvider) {
$interpolateProvider.startSymbol('{[{');
$interpolateProvider.endSymbol('}]}');
Directives
"Directives are a way to teach HTML new tricks. During DOM compilation directives are matched against the HTML and executed. This allows directives to register behavior, or transform the DOM.
Angular comes with a built in set of directives which are useful for building web applications but can be extended such that HTML can be turned into a declarative domain specific language (DSL)."
Directives - example
my_app.directive('limitinput', function () {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ctrl) {
scope.inputchanged = function () {
setTimeout(function () {
var limit = element.attr('limitinput');
var val = ctrl.$viewValue
if (val == undefined) return
var char_count = val.length;
if (char_count >= limit) {
attrs.$set('value', val.slice(0,limit))
scope.$apply(function() {
ctrl.$setViewValue(val.slice(0,limit));
});
}
},100)
}
element.keypress(scope.inputchanged)
.focus(scope.inputchanged)
.live('input paste', scope.inputchanged)
.on('ngChange', scope.inputchanged);
}
};
});
Ng-Cloak / NG-hide
AngularJS provides ng-cloak tag hiding
elements using CSS until scope is populated but...
What if there is only a promise? you get ugly looking page full with tags.
In that case: control menualy it with ng-hide
Template Filters
Example: add 'http://' to url
Django:
@register.filter(name='roojoom_legit_url')
def roojoom_legit_url(text):
if not value.startswith("http"):
value = 'http://' + text
else:
return text
AngularJS:
angular.module('filters', []).
filter('legit_url', function () {
return function (text) {
if (text != undefined) {
if (text.indexOf('http') != 0) {
text = 'http://' + text
}
return text
}
};
})
Loops
Django
{% for maintrek in not_featured.objects %} <div class="roojoom_box item"> <div class="roojoom_category"> <a href="/webtreks/category={{ maintrek.category.id }}"> <img class="category_icon" src="{{maintrek.category.icon }}" alt="category" />{{ maintrek.data.category.data.name }} </a> </div>
...
</div>
{% endfor %}
AngularJS
<div class="roojoom_box item" ng-repeat="maintrek in webtreks.objects"> <div class="roojoom_inner_box"> <div class="roojoom_category"> <a ng-href="/webtreks/category={[{ maintrek.category.id }]}"> <img class="category_icon" ng-src="{[{ maintrek.category.icon }]}" alt="category" />{[{ maintrek.category.name }]} </a> </div>
...
</div>
</div>
Interaction
Dealing with dynamic pages can easily done using directives.
ng-bind
or
Template:
ng-bind
<div ng-controller="Ctrl">
Enter name: <input type="text" ng-model="name">
<br>Hello <span ng-bind="name"></span>!
</div>
directives with templates
<div ng-controller="Ctrl">
<div show-input>
</div>
my_app.directive('showInput', function() { return { restrict: 'A', template: 'Enter name: <input type="text" ng-model="name"><br>Hello <span ng-bind="name"></span>!'
} });
Forms
auto validation
custom validation
Angular Vs. Django (Regular / Ajax)
Auto VALIDATION
<div ng-controller="Controller"> <form name="form" class="css-form" novalidate> Name:<input type="text" ng-model="user.name" name="uName" required />
<br /> E-mail:<input type="email" ng-model="user.email" name="uEmail" required />
<br /> <div ng-show="form.uEmail.$dirty && form.uEmail.$invalid">Invalid: <span ng-show="form.uEmail.$error.required">Tell us your email.</span> <span ng-show="form.uEmail.$error.email">This is not a valid email</span> </div>
<button ng-click="update(user)" ng-disabled="form.$invalid ||
isUnchanged(user)">SAVE</button> </form>
</div>
Custom Validation
Django:
Angular (Using directive)def clean(self, value): value = super(SetPasswordField, self).clean(value) min_length = app_settings.PASSWORD_MIN_LENGTH if len(value) < min_length: raise forms.ValidationError(_("Password must be a minimum of {0} " "characters.").format(min_length))
return value
var MIN_LENGTH = 6;
app.directive('validatePassword', function() {
return {
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
ctrl.$parsers.unshift(function(viewValue) {
if (viewValue > MIN_LENGTH) {
ctrl.$setValidity('MIN_LENGTH', true);
return viewValue;
} else {
ctrl.$setValidity('MIN_LENGTH', false);
return undefined;
}
});
}
};
});
Uploading
Use plug-ins
Upload using forms
Upload using API
Passing DATA & Variables
Creating angular resource
Passing data using template
Interacting with API resource / AJAX
Angular service
myModule.factory('serviceId', function() {
var shinyNewServiceInstance;
return shinyNewServiceInstance;
});
Using Template
<script type="text/javascript"> myModule.factory('serviceId', function(){ var shinyNewServiceInstance = {{django_data_json|safe}} ; return shinyNewServiceInstance; }) </script>
<script>
angular.module('serviceId').constant('user', { user: "{{ request.user.id }}", ... }).constant('urls', {
this_view_url: "{% url this_view %}", that_view_url: "{% url that_view %}", ...});
</script>
interacting with http requests and api
ng-resource ($http, $resource)
Restangular
Django - angular 0.1
Ajax requests from the controller
Form integration
Django - Angularjs
By Yftah Peled
Django - Angularjs
- 2,083