Backbone.js - error loading script - javascript

I have jquery.js, backbone.js ,underscore.js inlcuded in my html header (I can see these files from browser)
<script type='text/javascript'>
(function($){
var Student= Backbone.Model.extend({
initialize: function(){
console.log("studentis createrd");
}
});
var students= Backbone.Collection.extend({
model: Student
});
console.log(students.models);
})(jQuery);
</script>
I got this error message
UPDATE:html header
<script src="/static/js/jquery.js" type="text/javascript"> </script>
<script src="/static/js/backbone.js" type="text/javascript"></script>
<script src="/static/js/underscore.js" type="text/javascript"></script>

First you need to make sure that Backbone is loaded properly --
The order should be
---> jQuery
---> underscore
---> backbone
Next need to create a new instance of the collection
You cannot operate directly on the Model or Collection before creating an instance of it.
(function ($) {
var Student = Backbone.Model.extend({ // Created a Student model
initialize: function () {
console.log("studentis createrd");
}
});
var Students = Backbone.Collection.extend({ // Create a Students collection
model: Student
});
var student = new Student(); // Create a instance of Student model
var students = new Students(); // New instance of Students collection
students.add(student); // Add a model to the collection
console.log(students.models);
})(jQuery);
Check Fiddle

I think you also need to pass backbone as parameter to you function along with jQuery
<script type='text/javascript'>
(function($,Backbone){
var Student= Backbone.Model.extend({
initialize: function(){
console.log("studentis createrd");
}
});
var students= Backbone.Collection.extend({
model: Student
});
console.log(students.models);
})(jQuery,Backbone);
</script>

Per my comment:
When are you importing the backbone file?
Backbone has a dependency on underscore to work, so you need to have Jquery -> Underscore -> Backbone in order for backbone to load properly.

Related

Backbone.js primer customisation issues

I've been trying to get my first Backbone.js app up and running, following the Backbone.js primer here.
I've followed the example through and now I'm trying to customise it for my purposes which are to simply retrieve and read a JSON file from my server. I don't need to be able to change or delete any of the data.
I've set up my html as per the primer below:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Backbone.js Primer</title>
<script type="text/javascript" src="./node_modules/jquery/dist/jquery.min.js"></script>
<script type="text/javascript" src="./node_modules/underscore/underscore-min.js"></script>
<script type="text/javascript" src="./node_modules/backbone/backbone-min.js"></script>
<script type="text/javascript" src="./node_modules/moment/moment.js"></script>
<script type="text/javascript" src="./backbone.js"></script>
</head>
<body>
<div>
<h1>Transcripts Data</h1>
<div id="dailyTranscripts-app">
<ul class="dailyTranscripts-list"></ul>
</div>
</div>
</body>
</html>
I've then coded my backbone.js file as the primer describes below:
var yesterday = moment (new Date()).add(-1, 'days').format('YYYY-MM-DD')
var yesterdaysDataURL = 'https://mihndbotblob.blob.core.windows.net/mihndbot-transcripts/finalTranscripts/dailyTranscripts/' + yesterday + '.json'
// Model class for each transcript iten
var DailyTranscriptsModel = Backbone.Model.extend({
defaults: {
type: null,
MessageID: null,
MessageTime: null,
MessageChannel: null,
MessageSenderID: null,
MessageSenderName: null,
ConversationID: null,
MessageText: null,
MessageRecipientID: null,
QuickReplyDisplayText: null,
QuickReplyPayload: null,
Question: null,
Answer: null,
FollowUpPrompts: null
}
});
// Collection class for the DailyTransctipts list endpoint
var DailyTranscriptsCollection = Backbone.Collection.extend({
model: DailyTranscriptsModel,
url: yesterdaysDataURL
});
// View class for displaying each dailyTranscripts list item
var DailyTranscriptsListItemView = Backbone.View.extend({
tagName: 'li',
className: 'dailyTranscripts',
initialize: function () {
this.listenTo(this.model)
},
render: function () {
var html = '<b>Message ID: </b> ' + this.model.get('MessageID');
html += '<br><b>Message Time: </b>' + this.model.get('MessageTime');
this.$el.html(html);
return this;
}
});
// View class for rendering the list of all dailyTranscripts
var DailyTranscriptsListView = Backbone.View.extend({
el: '#dailyTranscripts-app',
initialize: function () {
this.listenTo(this.collection, 'sync', this.render);
},
render: function () {
var $list = this.$('ul.dailyTranscripts-list').empty();
this.collection.each(function (model) {
var item = new DailyTranscriptsListItemView({model: model});
$list.append(item.render().$el);
}, this);
return this;
}
});
// Create a new list collection, a list view, and then fetch list data:
var dailyTranscriptsList = new DailyTranscriptsCollection();
var dailyTranscriptsView = new DailyTranscriptsListView({collection: dailyTranscriptsList });
dailyTranscriptsList.fetch();
The major changes I've made to the code (apart from some customisations) are to remove the templates the primer uses to create the views (I couldn't get them working) and I've removed the Backbone CRUD elements as I only require my app to read data from the server, not update or delete it.
The issue I have is that whilst I'm pulling back the JSON file from the server, none of the data is rendering in the HTLM <div> as expected, it's just blank.
I know that Backbone.js is retrieving the data as when I add .then(function() {console.log(dailyTranscriptsList);}); to the final dailyTranscriptsList.fetch() call I can see the data in the browser console:
You need to wrap all of your backbone.js code within jQuery's .ready()
// backbone.js
$(document).ready(function () {
// all your backbone.js code here
})
This causes your js to run after the DOM is ready, so Backbone will know how to find the elements it needs in order for views to work.
You could also move <script type="text/javascript" src="./backbone.js"></script> to the end of the page, right before </body>

Passing a parameter to my Knockout ViewModel

I have an MVC site that uses Knockout JS. Basically, the MVC handles routing to a few different pages, and each page has a viewmodel.
One of the pages requires a parameter to filter the data. The code for the MVC Controller for that page is as follows:
public ActionResult Transactions(int policyId)
{
ViewData["policyId"] = policyId;
return View();
}
The View for that page includes a hidden field.
<input type="hidden" name="hldPolicy" value="#ViewData["policyId"]">
Then after the html for the page,
#section scripts
{
#Scripts.Render("~/bundles/myBundle")
<script>
$(document).ready(function () {
var policyId = $('#hldPolicy').val();
var transactionViewModel = new TransactionViewModel(policyId);
ko.applyBindings(transactionViewModel);
});
</script>
}
The problem is this doesn't work because the hidden field is undefined when the script runs. That doesn't make sense to me as I thought that was what the $(document).ready was protecting against. What am I doing wrong here? And is there a better way to pass a parameter from the URL params into the viewmodel?
You can use it like this. Here you dont actually have to pass the parameter instead define a function which will be called on viewmodel initialization and get the data according to your requirements.
#section scripts
{
#Scripts.Render("~/bundles/myBundle")
<script type="text/javascript">
function TransactionViewModel(){
var self = this
self.SomeProperty = ko.observable()
self.LoadData = function(){
var policyId = $('#hldPolicy').val();
self.SomeProperty(policyId)
}
self.LoadData()
}
$(document).ready(function () {
ko.applyBindings(new TransactionViewModel());
});
</script>
}
When knockout model will be initialized it will call self.LoadData() automatically.
EDIT
I found you are missing id attribute at your input
<input type="hidden" id="hldPolicy" name="hldPolicy" value="#ViewData["policyId"]">
Now it should work properly.
EDIT:
You can also do it like this
#section scripts
{
#Scripts.Render("~/bundles/myBundle")
<script type="text/javascript">
function TransactionViewModel(policyId){
var self = this
self.SomeProperty = ko.observable()
self.LoadData = function(policyId){
self.SomeProperty(policyId)
}
self.LoadData(policyId);
}
$(document).ready(function () {
var policyId = $('#hldPolicy').val();
ko.applyBindings(new TransactionViewModel(policyId));
});
</script>
}

How to fetch data from Backbone collection to Template

i am just writing a simple backbone program. But i am not getting how to fetch data from backbone collection to backbone template. Complete code is written below:
<!doctype html>
<html>
<head>
<title>Backbone tutorial</title>
</head>
<body>
<div class="user">user</div>
<div class="page"></div>
<script type="text/template" id="user-list-template">
I am not able to get data on daya.key
<h1> <%= data.key %> </h1>
</script>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="underscore.js"></script>
<script type="text/javascript" src="backbone.js"></script>
<script>
This is my Collection code
var Album = Backbone.Collection.extend({
url : "/data.json"
});
This is my view code
var UserList= Backbone.View.extend({
el:'.page',
template:_.template($('#user-list-template').html()),
render : function(){
var that=this;
var album= new Album();
album.fetch({
success:function(album){
var _data = {data : album.models} ;
$(that.el).html(that.template(_data));
}
})
}
});
This is my Router code
var Router = Backbone.Router.extend({
routes: {
"": "home" // #help
}
});
var userList= new UserList();
var router = new Router();
router.on('route:home', function(){
userList.render();
});
Backbone.history.start();
</script>
</body>
</html>
and here is the data.json file
{ "key" : "value to print on template "}
Two modifications i would suggest
1.First check the data feild in your template. Since you are fetching data from the collection it will be array of models.
<h1> <%= data[0].key %> </h1>
or you can use a for loop iterating over the collections
2.The data.json file should look like this
[{"key" : "value"}]
Server needs to return a JSON array of model object for collection.fetch() request. So the data.json should look like this:
[{"key":"value to print on template"},{"key":"another value"}]
And try this collection view render implementation:
Model:
var User = new Backbone.Model.extend({});
Collection:
var Album = new Backbone.Collection.extend({
model: User,
url: "/data.json"
});
//create collection instance
var album = new Album();
View:
var UserList= Backbone.View.extend({
el:'.page',
template:_.template($('#user-list-template').html()),
initialize: function(){
//register a collection data add event handler
this.listenTo(album,"add",this.addUser);
//register a collection data remove event handler
this.listenTo(album,"remove",this.removeUser);
album.fetch();
},
render : function(){
},
addUser: function(user){ //apply model data to view template and append to view element
this.$el.append(this.template(user.toJSON()));
},
removeUser: function(user){
//view state update implementation when data have been removed from collection
}
});
Template:
<script type="text/template" id="user-list-template">
<h1><%= key %></h1>
</script>
div.user view will add/remove user-list view dynamically according to collection data manipulation.
Hope this helpful.

backbone collection. fetch() not rendering the view in mozilla

i am trying to learn backbone.js ( Backbone.js 1.0.0) this is my sample html page where iam using collection. fetch() method to get the collection,and it is displayed using view .i am getting result in
google chrome,but nothing is displayed in mozilla. i don't know the exact reason.
while i refere to backone site http://backbonejs.org/#Collection-fetch
it is qouted that :
Note that fetch should not be used to populate collections on page load — all models needed at load time should already be bootstrapped in to place. fetch is intended for lazily-loading models for interfaces that are not needed immediately: for example, documents with collections of notes that may be toggled open and closed.
is this is related with my issue?
this is my sample html page
<!DOCTYPE html>
<html>
<head>
<title>Backbone Application</title>
<script src="js/jquery.js" type="text/javascript"></script>
<script src="js/underscore.js" type="text/javascript"></script>
<script src="js/backbone.js" type="text/javascript"></script>
</head>
<body>
<div class="list"></div>
<script id="personTemplate" type="text/template">
<td> <strong><%= name %></strong></td>
<td>(<%= age %>) </td>
<td> <%= occupation %> </td>
</script>
<script type="text/javascript">
//Person Model
var Person = Backbone.Model.extend({
defaults: {
name: 'Guest User',
age: 30,
occupation: 'worker'
}
});
// A List of People
var PeopleCollection = Backbone.Collection.extend({
model: Person,
initialize: function(){
alert("intialise")
},
url:'/RestFul/rest/members/info',
});
// View for all people
var PeopleView = Backbone.View.extend({
tagName: 'table',
render: function(){
this.collection.each(function(person){
var personView = new PersonView({ model: person });
this.$el.append(personView.render().el); // calling render method manually..
}, this);
return this; // returning this for chaining..
}
});
// The View for a Person
var PersonView = Backbone.View.extend({
tagName: 'tr',
template: _.template($('#personTemplate').html()),
////////// initialize function is gone from there. So we need to call render method manually now..
render: function(){
this.$el.html( this.template(this.model.toJSON()));
return this; // returning this from render method..
}
});
var peopleCollection = new PeopleCollection();
//peopleCollection.fetch();
peopleCollection.fetch({ success: function () { console.log("collection fetched"); } });
//peopleCollection.fetch({context:collection}).done(function() {
// console.log(this.length)
// })
//console.log(peopleCollection.toJSON())
alert(JSON.stringify(peopleCollection));
var peopleView = new PeopleView({ collection: peopleCollection });
$(document.body).append(peopleView.render().el); // adding people view in DOM
</script>
</body>
</html>
any help will be appreciated
Try with
var fetching = peopleCollection.fetch({ success: function () { console.log("collection fetched"); } });
$.when(fetching).done(function(){
var peopleView = new PeopleView({ collection: peopleCollection });
$(document.body).append(peopleView.render().el); // adding people view in DOM
});
var fetching = peopleCollection.fetch({ success: function () {
var peopleView = new PeopleView({ collection: peopleCollection });
$(document.body).append(peopleView.render().el);
} });
I think we can call the view render inside the success callback

passing model object to view in backbone

I have been trying to pass a model object to be evaluated in my template but had no luck. I tried the following but had no luck
dashboardmodel.js
var myMod = Backbone.Model.extend({
defaults: {
name: "mo",
age: "10"
}
});
myview.js
var dashView = Backbone.View.extend({
el: '.content-area',
this.mymodel = new myMod({}),
template: _.template(dashBoardTemplate, this.mymodel),
initialize: function() {
},
render: function() {
this.$el.html(this.template);
return this;
}
// more javascript code.............
dahboard.html
<p> Hello <%= name %> </p>
PS: I am using the underscore template engine
In addition , your way to pass a model to a view is not flexible, because you would pass an instance of your model, instead of a default model. Thus, you might want to single out
this.mymodel = new myMod({}),
(btw, above line gives me error message in my chrome browser because of "=" sign)
Then, suppose you have an instance A:
A = new myMod({"name": "World", "age":100})
Then pass it to your view as:
myview = new dashView({mymodel: A})
One more step, you have to do is to call render function:
myview.render();
Here's a complete solution:
<html>
<script src="jquery-1.10.2.min.js"></script>
<script src="underscore-min.js"></script>
<script src="backbone.js"></script>
<body>
<script type="text/template" id="dashBoardTemplate">
<p> Hello <%= name %> </p>
</script>
<div class="content-area">
</div>
<script type="text/javascript">
var myMod = Backbone.Model.extend({
defaults: {
name: "mo",
age: "10"
}
});
var dashView = Backbone.View.extend({
el: '.content-area',
template: _.template($("#dashBoardTemplate").html()),
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});
mymod = new myMod({"name": "World", "age":100});
myview = new dashView({model:mymod});
myview.render();
</script>
</body>
</html>
If you want to study backone.js, please read this open source book which get me started:
http://addyosmani.github.io/backbone-fundamentals/
You need to get properties of a Backbone Model with the getter syntax, so you need to rewrite your template to:
<p> Hello <%= obj.get('name') %> </p>
Or you need to convert your model into a plain JS object when calling _.template what you can do with the .toJSON() (which creates a clone of the model) or .attributes property:
template: _.template(dashBoardTemplate, this.mymodel.toJSON())
Side note: you should consider to move the template rendering logic into your view. Because your current code render your template when your view is declared and not when you call the render method. So you might get unexpected result. So your code you look like this:
template: _.template(dashBoardTemplate), //only compile the template
render: function() {
this.$el.html(this.template(this.mymodel.toJSON()));
return this;
}

Categories

Resources