I have the following code and was wondering why my data isn't getting pulled into my model? I'm using a static json file and I'm guessing this might be my problem but can't seem to find any documentation about it.
var DataModel = Backbone.Model.extend({
initialize: function () {
console.log('initiliazed model')
},
url: "data/data.json"
});
var StructureView = Backbone.View.extend ({
initialize: function () {
console.log('initiliazed view')
_.bindAll(this);
this.model.fetch();
this.render();
this.model.on('change',this.render);
},
el : '#ev-wrapper',
render: function () {
$('#ev-wrapper').empty().append(Handlebars.compile($('#ev-template').html())(this.model.toJSON()));
$('.ev-asset-loader').fadeOut('slow');
}
});
var structureView = new StructureView({model: new DataModel()});
You need to call fetch. This will issue an AJAX request using url
var model = new DataModel();
model.fetch();
Open Firebug or your favorite browser's network console to see AJAX requests and check if it's OK
Related
I following this example
https://forge.autodesk.com/blog/aggregate-multi-models-sequence-forge-viewer
for loading multi model into Forge Viewer but sometimes I got this error:
Cannot read property 'isEmpty' of undefined.
When i try to reload the page again sometime it don't have this error, i don't know why. Can you please help. Thank you very much
Snapshot
This is my request for token
function getForgeToken(callback) {
jQuery.ajax({
url: '/token',
success: function (res) {
callback(res.access_token, res.expires_in)
}
});
}
And for Initialize token error, Load failure error
var token = getForgeToken;
var options = {
env: 'AutodeskProduction',
getAccessToken: token
};
//It looks the static function of Viewer does not support ES6
//still use ES5
Autodesk.Viewing.Initializer(options, function onInitialized(){
//get the viewer div
const viewerDiv = document.getElementById( 'forgeViewerLocal' );
//initialize the viewer object
const viewer = new Autodesk.Viewing.Private.GuiViewer3D( viewerDiv);
//load model one by one in sequence
const util = new MultipleModelUtil( viewer );
util.processModels( models);
});
launchViewer( models.concat() );
I'm new to BackboneJS but I'm doing my best to learn it. I'm more familiar with AngularJS so I have some confusion in BackboneJS but would definitely want to become an expert BackboneJS developer too.
Back at my previous job, I was the frontend dev and I would work with the Java dev guy. We would have a meeting about how the JSON response would look like. Basically, I'll make a REST call(either with Restangular or $http) to one of their endpoints and I'll get a response. The JSON response will be assigned to a scope variable such as $scope.bookCollection. In my template, I'll just use ng-repeat to display it.
Now with BackboneJS, I'd like to do it properly. I read today that a BackboneJS Model is a container. What I'd like to happen is that after making a fetch(), I want the JSON response to be put in the Model that I defined. How is that done?
I found an example jsfiddle but I think it's a very bad example. I can't find something that is helpful right now, something with a good fetched data.
require.config({
paths: {
jquery: 'http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min',
underscore: 'http://underscorejs.org/underscore',
backbone: 'http://backbonejs.org/backbone-min'
},
shim: {
backbone: {
deps: ["underscore", "jquery"],
exports: "Backbone"
},
underscore: {
exports: "_"
}
}
});
require([
'jquery',
'underscore',
'backbone'], function ($, _, Backbone) {
var UserModel = Backbone.Model.extend({
urlRoot: '/echo/json/',
defaults: {
name: '',
email: ''
}
});
var userDetails = {
name: 'Nelio',
email: 'nelio#angelfire.com'
};
var user = new UserModel(userDetails);
user.fetch({
success: function (user) {
console.log(user.toJSON());
}
});
});
Here is the jsfiddle:
http://jsfiddle.net/20qbco46/
I want the JSON response to be put in the Model that I defined. How is
that done?
If you are trying to render the data from you model, you will use a view for this:
First, create a view to render your data:
// Create a new view class which will render you model
var BookView = Backbone.View.extend({
// Use underscores templating
template: _.template('<strong><%= title %></strong> - <%= author %>'),
initialize: function() {
// Render the view on initialization
this.render();
// Update the view when the model is changed
this.listenTo(this.model, "change", this.render);
},
render: function() {
// Render your model data using your template
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});
See also: template and toJSON as well as $el
Next, create a Model:
// Create a model class
var Book = Backbone.Model.extend({
urlRoot: '/echo/json/',
defaults: {
title : '',
author: ''
},
});
Your model will hold the data fetched from the url / urlRoot
You can use set if you are trying to add new attributes to your model.
You can use get to grab attributes from your model.
See also - save and destroy.
Then, instantiate your model:
// Some dummy data
var instance = {
title: 'learn Backbone JS',
author: 'Bobby Longsocks',
};
// Instansite your model
var model = new Book(instance);
And finally, fetch your model data and create a new instance of you view:
// Fetch your model
model.fetch({
success: function(book) {
// Instansite your view, passing in your model
var view = new BookView({model: book, el: $('body')});
}
});
Here is an Example you can fiddle with.
And some further reading: Annotated Source
I'm trying to parse JSON data using Backbone from a remote API. Here's what I've got so far:
// --------------------------------------------------
// MODELS
// --------------------------------------------------
var VideoModel = Backbone.Model.extend({
idAttribute: '_id',
parse: function(){
this.id = response._id;
}
});
var videoModel = new VideoModel({ parse:true });
// --------------------------------------------------
// COLLECTIONS
// --------------------------------------------------
var VideosCollection = Backbone.Collection.extend({
model: VideoModel,
url: 'redacted',
parse: function(response){
this.videos = response.data;
this.cid = response.cid;
return response.data;
},
render: function(){
this.collection.forEach(this.addone, this);
}
});
var videosCollection = new VideosCollection();
videosCollection.fetch({
success: function(videos){
console.log('success!');
},
error: function(){
console.log('failed.');
}
});
// --------------------------------------------------
// VIEWS
// --------------------------------------------------
var VideoView = Backbone.View.extend({
template: _.template('<%= videoModel.id %>'),
render: function(){
this$el.html(this.template(this.model.attributes));
return this;
}
});
var videoView = new VideoView({});
var VideosCollectionView = Backbone.View.extend({});
var videosCollectionView = new VideosCollectionView({
collection: videosCollection,
render: function(){
this.collection.forEach(this.addOne, this);
},
addOne: function(videoModel){
this.$el.append(videoView.el);
}
});
What I'm having trouble with is that console.log(videoModel.id) is still undefined.
The data is a playlist of videos, which is valid JSON:
{
"total":24,
"per_page":24,
"current_page":1,
"last_page":1,
"from":1,
"to":24,
"data":[
{
"_id":"55d1bb50140ba04c1d8b4583",
Be glad for some prompts in the right direction - especially since I had it working this morning and then ... reverted to a previous version without saving.
Thanks
From documentstion of parse method:
The function is passed the raw response object, and should return the
attributes hash to be set on the model. The default implementation is
a no-op, simply passing through the JSON response.
So by default it works like this:
parse: function(data) {
return data;
}
Your code now returns nothing and model takes no data.
As I see you want to set id attribute but you already have setted idAttribute property with _id and there is _id in your data so it should work fine without parse at all. Try to remove it.
The answer is that I was trying to parse via a Collection instead of a Model. So I would never have got the id I was looking for. For some reason.
I needed to move the URL into the Model and parse from there:
var VideoModel = Backbone.Model.extend({
idAttribute: '_id',
url: 'redacted',
parse: function(response){
var id = response._id;
var cid = response.cid;
return response.data;
},
}),
Now when I do videoModel.get(1) in the console, it returns the value of the first item in my array.
I have the following code but am struggling to get my view to render the template instead of my model. It all works fine if I render the handlebars template through my model but would like to separate my code into the view.
var DataModel = Backbone.Model.extend({
initialize: function () {
$.getJSON('js/data.json',function(data){
$('.one-wrapper').append(Handlebars.compile($('#one-template').html())(data));
$('.one-asset-loader').fadeOut('slow');
});
},
defaults : function () {
},
});
var StructureView = Backbone.View.extend ({
initialize: function () {
}
});
var structureView = new StructureView({model: new DataModel()});
You can access the model inside the view using this.model.
Your code should look something like:
var StructureView = Backbone.View.extend ({
initialize: function () {
_.bindAll(this);
this.render();
this.model.on('change',this.render);
},
render: function() {
$('.one-wrapper').empty().append(Handlebars.compile($('#one-template').html())( this.model.toJSON() ));
}
});
This will work assuming your model actually contains the data. To do this you need to use the model.url and model.fetch() (not $.getJSON)
I am trying to use backbones.js fetch to get json from a twitter search
and my code below can someone tell me where I am going wrong?
(function($){
var Item = Backbone.Model.extend();
var List = Backbone.Collection.extend({
model: Item,
url:"http://search.twitter.com/search.json?q=blue%20angels&rpp=5&include_entities=true&result_type=mixed"
});
var ListView = Backbone.View.extend({
el: $('#test'),
events: {
'click button#add': 'getPost'
},
initialize: function(){
_.bindAll(this, 'render', 'getPost');
this.collection = new List();
this.render();
},
render: function(){
var self = this;
$(this.el).append("<button id='add'>get</button>");
},
getPost: function(){
console.log(this.collection.fetch());
}
});
// **listView instance**: Instantiate main app view.
var listView = new ListView();
})(jQuery);
I am just getting started with backbone and I just want to console.log the json
you can see my example here. jsfiddle.net/YnJ9q/2/
There are two issues above:
Firstly, you need to add a success/fail callback to the fetch method in order for you to have the fetched JSON logged to the console.
getPost: function(){
var that = this;
this.collection.fetch(
{
success: function () {
console.log(that.collection.toJSON());
},
error: function() {
console.log('Failed to fetch!');
}
});
}
Another problem is the issue of "same-origin-policy'. You can find out how to resolve that by taking a look at this link.
Update:
I modified your code and included the updated sync method. It now works! Take a look here!
Basically, update your collection to include the parse and sync methods as below:
var List = Backbone.Collection.extend({
model: Item,
url: "http://search.twitter.com/search.json?q=blue%20angels&rpp=5&include_entities=true&result_type=mixed",
parse: function(response) {
return response.results;
},
sync: function(method, model, options) {
var that = this;
var params = _.extend({
type: 'GET',
dataType: 'jsonp',
url: that.url,
processData: false
}, options);
return $.ajax(params);
}
});