I am used to defining my django views with http request that send http response back with a python dictionary of data that i can iterate over and display. I am attempting to replace this with the use of backbone.js.
Currently i have a set up like so:
<ul id="teaching_students">
{% for student in students.object_list %}
<li class="selected">
<span> {{ student.name }} </span>
</li>
{% endfor %}
</ul>
and i would like to use ICanHaz.js and Mustache.js as javascript templates to fill {{ student.name}} on the client side.
Using tastypie so far, i have a PersonResource which has all the students coming back as json objects when the following url is passed.
http://127.0.0.1:8000/api/people/?format=json
Do i need to generate an API view for this url in views.py, if so what does that look like?
How do i call, in backbone.js, this url and set up a collection, view and a correct route ?
My client side structure is broken down into views/models (i use require.js to bring them together).
I am using several plugins to help bridge the gap between backbone and tastypie (backbone-tastypie.js) but i really want to see how others have replaced traditional django template rendering with REST api's and backbone.js
EDIT: Adding Backbone model, here is the model i am using
define([
'underscore',
'backbone'
], function(_, Backbone) {
var PersonModel = Backbone.Model.extend({
defaults : {
},
initialize: function( options ) {
},
parse : function(res) {
// because of jsonp
return res.data;
}
});
return PersonModel;
});
So you want to move from server side rendering to client side rendering? This means
you incur additional http requests. But it's possible.
Do i need to generate an API view for this url in views.py, if so what
does that look like?
Tasty pie does all the work once you've specified your ModelResource and urlpattern.
There's no need for you to have another function in your app's views.py to handle the http request-response cycle.
Check out the tasty pie tutorial to learn how to hook your resource to a url.
Use a test REST client like the Postman chrome extension to see if everything's ok.
How do i call, in backbone.js, this url and set up a collection, view
and a correct route ?
Treat the api like any other. Set up the url field of your model to
/api/people/?format=json
Have your view listen to the change event of PersonModel
Fetch the model.
Render the view using the templating engine of your choice when the data is received.
Also see Adding REST to Django for options on providing RESTful interfaces to django apps.
Related
I want to implement pagination in my "angularJs" application. I have a dropdown menu that I'm using angular-ui for that. I want at first application loads the first set of data from "API" and when scrolled to button with the help of ngInfiniteScroll requests the next set of data from the "API". For example at first in request "URL" I add "page=1" as parameter and for any request I add to that "page" number.
My question is that for this pagination should the "API" has the pagination capability or I can do this for any "API"?
If the "API" need to have that capability, do you know any "API" with pagination capability so I can test my application?
Appreciate any help.
my code is here
The API has to support pagination in the sense that it should be able to respond to queries with fragments of data, instead of dumping all the data in one go.
For example:
For page 1:
your.api.endpoint/your/resource/path/countries?offset=0&pageSize=50
For page 4:
your.api.endpoint/your/resource/path/countries?offset=200&pageSize=50
You can build your URL params for pagination however you want though, e.g. /countries?pageNo=4&pageSize=50, /countries?from=200&to=250 etc.
Note:
When you implement server-side pagination, you need to implement server-side sorting and filtering too; that's because with server-side pagination the client can only see 1 page of data and therefore sorting or filtering would be inaccurate.
EDIT to show example of mocking API response
In your service you might have something like this:
return $http({
method: 'GET',
url: 'your.api.endpoint/your/resource/path/countries?offset=200&pageSize=50'
})
And you'd replace it with:
var pageOfData = { ... }; // Mocked data here.
return $q(function (resolve, reject) {
resolve(pageOfData);
});
I use drupal as backend and as texts manager.
So I want to insert string keys in html and then send request with all keys for getting real text in current lang.
So I want to make some stuff like
<h4 ng-gettext>MODULE_Y__STRING1</h4>
<span ng-gettext>MODULE_X__STRING1</span>
<span ng-gettext>MODULE_X__STRING3</span>
Then in NgGettext directive I want to send request with all strings like
var strings = [];
EACH.('ng-gettext', function(){
strings.push($(this).html());
});
$.when('/api/gettexts', {keys: strings}).then(function(){
// here I need to replace all keys with texts.
});
Is there any ellegant Angular way to do this or maybe some plugins?
You can use the angular-translate module for that. It has a few plugins for asynchronous loading (from server for example), see here : https://angular-translate.github.io/docs/#/guide/12_asynchronous-loading
You'll have something like :
$translateProvider.useUrlLoader('api.php/translations.json');
I am wondering if it's a good practice to use the same URL to provide both the HTML and JSON response.
For example if I am building a blog and I have a URL that provides the latest items, I would have a URL like /latest
I would like to use the same URL for my endpoint in angular to retrieve the items so I have following route in my node implementation:
app.get("/latest",function(req,res){
var type = req.header("Accept");
if(type.indexOf("application/json") > -1){
getLatestItems(req,res);
}
else {
res.render("/latest", {user: req.session.username, current: "latest"});
}
});
I was wondering if this approach is OK or is it better to have a separate set of endpoints for my JSON responses?
I would create a separate URL pattern for your backing API.
So in Angular you can still have a URL route /latest, but you will provide the JSON data via a URL like /api/latest.
This will create less confusion and also allow you to easily integrate the API with other stuff since it will only be returning JSON.
I have an HTML page that's been generated on the server. It contains data similar to this:
<ul>
<li>Banana</li>
<li>Apple</li>
<li>Pear</li>
</ul>
Is it possible to "angularize" (or "post-compile") such data to obtain the same behavior as if the list had been generated with:
<ul>
<li ng-repeat="item in items">{{item.name}}</li>
</ul>
That way, my list would be sortable, filterable, etc.
Why would I want to do that?! ;-)
I'm using Drupal as my page generator and for multiple reasons I'd like to keep it that way (my content is translatable, themable with Drupal's theme functions, etc.)
Having the initial version of the page fully rendered by the server makes it indexable by search engines. The AngularJS behaviors are mostly just UI enhancements.
I'd like to avoid an additional roundtrip to the server just to re-transfer the same data.
Caveats:
I'm not just asking how to implement the desired behavior with AngularJS + Drupal (I could expose Drupal's data via an endpoint to which AngularJS would send requests). Instead, I'm asking how to recycle data that's already in the HTML to turn it into an AngularJS model (without resorting to ngInit, ideally).
What I am asking breaks the MVC pattern, I know.
In case you're curious, the site is http://ng-workshop.com/ (it's a collection of AngularJS resources and tutorials).
Thanks!
One way to provide angular the data is to echo out the php data to the page as a javascript object above the other included scripts on the page.
$dbResult = ['f1', 'f2', 'f3'];
echo "<script type='text/javascript'> var php_data = " . json_encode($dbResult) . ";</script>";
then somewhere in your angular js code...
$scope.items = php_data || [];
You may want to place the data in a namespaced javascript object to prevent any kind of stomping on.
Example:
PHP -> echo "myApp.page.data =" . json_encode($dbResult) . ";"
Angular -> $scope.items = myApp.page.data || [];
Just want to know your idea wht will be my approach on how to store external json data file into a services so that i can inject it into different controllers
Thanks
Try to use ngTranslation module.
with this service you can store the static content(some json file, etc..) outside of the code, and not dirty your controllers/services...
EXAMPLE:
JS:
angular.module('app', ['ng-translation'])
.config(['ngTranslationProvider', function(ngTranslationProvider) {
ngStaticProvider
.setDirectory('/assets/static')
.setFilesSuffix('.json')
.langsFiles({
demo1: 'demo1',
demo2: 'demo2'
})
}]);
//inject to controller
function PanelController($scope, translateFilter) {
$scope.panelContent = translateFilter('key','fileName')
}
HTML:
<!-- use as a filter {{ key | translate: fileName }}-->
<p>{{ key | translate: fileName }}</p>
<!-- use ng-translate directive, similar to ng-bind-->
<p ng-translate="file(key)"></p>
Well, it all depends on the architecture of your application but I guess you could create a factory or service that will store data then simply inject that factory wherever needed.
If the data needs to be persistent, I would use something like localStorage. If it's a really small amount of data and your app cannot support HTML5, I would use cookies.
The more you elaborate the more accurate answer you will get.
Have look at the angularjs tutorial. It specifically address this issue.
First go though http://docs.angularjs.org/tutorial/step_05 where you include the json in controller.
Then follow http://docs.angularjs.org/tutorial/step_11 where it is moved to service.
$http.get() can be used to retrive data from REST urls as well.