Backbone Marionette events, Zurb Foundation's Reveal Modals - backbone.js

I'm building a modal popup by jamming a Backbone Marionette itemview into a Foundation Reveal modal. The modals appear but no events fire. Specifically, I'm trying to catch a click event.
I load Foundation from a Marionette Layout view.
'use strict';
define([
'jquery',
'underscore',
'backbone',
'region/actionbar',
'region/modal',
'text!/js/template/global.ejs',
'js/views/actionbar/actionbar.js',
'less!/style/global.less',
'css!/js/bower_components/foundation/css/foundation.css',
'/js/bower_components/foundation/js/foundation/foundation.js',
'/js/bower_components/foundation/js/foundation/foundation.reveal.js',
'marionette'
], function ($, _, Backbone, ActionBar, Modal, Template, ActionBarView) {
var GlobalLayout = Backbone.Marionette.Layout.extend({
template: _.template(Template),
el: 'body',
regions: {
content: "#content",
actionBar: ActionBar,
modal: '#modal'
},
initialize: function(){
},
onRender: function(){
// Load foundation
$(document).foundation();
},
title: function(title) {
// this.actionbar.title(title);
// document.title = "Workbench :: " + title;
}
});
var layout = new GlobalLayout();
layout.render();
return layout;
});
The popup is being loaded from a click event in a view in the actionbar region. Here's the Region:
'use strict';
define([
'jquery',
'underscore',
'backbone',
'marionette'
], function ($, _, Backbone) {
var ActionBar = Backbone.Marionette.Region.extend({
el: "#action-bar"
});
return ActionBar;
});
...and here's the View in that region. onSignUp() jams my SignUp modal into the Modal region. It then re-initializes foundation.
'use strict';
define([
'jquery',
'underscore',
'backbone',
'layout/global',
'/js/views/modals/sign-up.js',
'/js/views/modals/sign-in.js',
'model/user',
'text!/js/template/actionbar/actionbar.ejs',
'less!/style/global.less',
'marionette'
], function ($, _, Backbone, layout, SignUp_Modal, SignIn_Modal, User, Template) {
var ActionBarView = Backbone.Marionette.ItemView.extend({
initialize: function(){
this.setElement('#action-bar');
},
template: _.template(Template),
events: {
"click .sign-in" : "onSignIn",
"click .sign-up" : "onSignUp"
},
onSignUp: function(e){
// e.preventDefault();
layout.modal.show( new SignUp_Modal() );
$(document).foundation();
},
onSignIn: function(e){
// Prevent the link from doing anything.
e.preventDefault();
// Load modal popup that requests user to sign in
layout.modal.show( new SignIn_Modal() );
$(document).foundation();
}
});
return ActionBarView;
});
Finally, here's my SignUp_Modal view and its template.
'use strict';
define([
'jquery',
'underscore',
'model/user',
'text!/js/template/modals/sign-up.ejs',
'marionette'
], function ( $, _, User, Template){
var Modal = Backbone.Marionette.ItemView.extend({
events: {
'click #join': 'onJoin',
'click .me': 'onJoin'
},
template: _.template(Template),
onJoin: function(e){
// Check whether the click events do anything
console.log('Heard it');
}
});
return Modal;
});
Template:
<div id="signUp" class="reveal-modal" data-reveal>
<form>
<div class="row">
<div class="small-8">
<div class="row">
<div class="small-3 columns">
<label for="email" class="right inline">Email</label>
</div>
<div class="small-9 columns">
<input type="text" id="email" placeholder="Email">
</div>
</div>
<div class="row">
<div class="small-3 columns">
<label for="phone" class="right inline">Phone</label>
</div>
<div class="small-9 columns">
<input type="text" id="phone" placeholder="Phone">
</div>
</div>
<div class="row">
<div class="small-3 columns">
<label for="pass" class="right inline">Password</label>
</div>
<div class="small-9 columns">
<input type="password" id="pass">
</div>
</div>
<div class="row">
<label>Username will be...</label>
<input type="radio" name="username" value="email" id="username_email" checked><label for="username_email">Email</label>
<input type="radio" name="username" value="phone" id="username_phone"><label for="username_phone">Phone</label>
</div>
<div class="row">
<div class="small-3 columns">
Join
</div>
</div>
</div>
</div>
</form>
<div class="me">blaaaa</div>
<a class="close-reveal-modal">×</a>
</div>
I'm betting any of these would be helpful:
Boilerplate example showing how to implement Zurb Foundation with a backbone project, specifically where you're jamming a backbone view into a foundation modal?
Any general reasons why views don't hear click events?
Have I improperly loaded the view into the region?
The error occurs specifically when I click either the element with class="me" or id="join". Both of these should call onJoin() but neither do.

The events are not being trigger because foundation creates a new DOM element to hold the modal, this element is outside of your ItemView's instance's el, and as you might know Backbone only delegate events to the element associated with the view.

Related

Angular controller loads but ng-repeat doesn't show

I'm learning angularJS and I'm having an issue trying to use ng-repeat.I know that the template and controller are loading because I did a console.log(self.post) test that shows the single post that I expect from the demoSuggestions and the template loads the comCtrl.post.title that I expect. But the ng-repeat='comment in comCtrl.post.comments doesn't show anything. Any ideas as to what I'm doing wrong?
HTML
<script type='text/ng-template' id='/suggestions.html'>
<div class='row' ng-controller='commentsController as comCtrl'>
<div class='col-xs-12'>
<div class='commentTitle'>
<h3 class='text-center'>{{comCtrl.post.title}}</h3>
</div><!--End of commentTitle-->
</div><!--End of col-->
</div><!--End of row-->
<div class='row' ng-repeat='comment in comCtrl.post.comments'>
<div class='col-xs-12 col-sm-10 col-sm-offset-1'>
<div class='commentContainer'>
<div class='row'>
<div class='col-xs-3 col-sm-2 col-md-1'>
<div class='thumbsUp'>
<i class="fa fa-thumbs-up" ng-click='comCtrl.upVote($index)'></i>
<span>{{comment.upvotes}}</span>
</div><!--End of thumbsUp-->
</div><!--End of col-->
<div class='col-xs-9 col-sm-10 col-md-11'>
<div class='commentBody'>
<span>{{comment.body}}</span>
</div><!--End of commentBody-->
</div><!--End of col-->
</div><!--End of row-->
</div><!--End of commentContainer-->
</div><!--End of col-->
</div><!--End of row-->
<div class='row'>
<div class='col-xs-12'>
<form id='comment' ng-submit="addComment()" style="margin-top: 50px">
<h3> Submit Your Comment </h3>
<div class="form-group">
<input type="text" class="form-control" placeholder="Place comment here" ng-model="body"></input>
</div><!--End of form-group-->
<button type="submit" class="btn btn-danger">Suggest</button>
</form>
</div><!--End of col-->
</div><!--End of row-->
</script>
Module & config
var suggestionApp = angular.module('suggestionBox', ['ngRoute'])
.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: '/home.html',
})
.when('/suggestion/:id',{
templateUrl:'/suggestions.html'
})
.otherwise({
redirectTo:'/'
});
}]);
Controller & Service
.controller('commentsController',['$routeParams','suggestions', function($routeParams, suggestions){
var self = this;
var swap = 1;
self.post = suggestions.posts[$routeParams.id];
console.log(self.post)
self.addComment = function() {
self.post.comments.push({
body:self.body,
upvotes:0
});
};
self.upVote=function(index){
if(swap)
{
self.post.comments[index].upvotes += 1;
$('.thumbsUp .fa').eq(index).css('color','red');
swap=0;
}
else
{
self.post.comments[index].upvotes -= 1;
$('.thumbsUp .fa').eq(index).css('color', 'black');
swap=1;
}
};
}])
.factory('suggestions', [function(){
var demoSuggestions = {
posts: [
{
title: 'Term limits on congress',
avatar:'https://upload.wikimedia.org/wikipedia/commons/7/7a/US_Navy_040521-N-9909C-006_Established_by_the_American_Battle_Monuments_Commission,_the_memorial_honors_all_military_veterans_of_World_War_II.jpg',
upvotes: 15,
comments: [
{body:'love the idea',upvotes:0},
{body:'let\'s make this happen', upvotes:0},
]
},
{
title: 'Every two years a popular vote on two issues that passes into law without Congress.',
avatar:'https://upload.wikimedia.org/wikipedia/commons/3/3e/The_Marine_Corps_War_Memorial_in_Arlington,_Va.,_can_be_seen_prior_to_the_Sunset_Parade_June_4,_2013_130604-M-MM982-036.jpg',
upvotes: 9,
comments: [
{body:'Only if the judicial branch still rules on its constitutionality.', upvotes:0},
{body:'Do you really think people would come out to vote?', upvotes:0},
{body:'I\'d be down for this',upvotes:0}
]
},
{
title: 'Create a biometric scanner for all those entering the country.',
avatar:'https://upload.wikimedia.org/wikipedia/commons/e/ea/Washington_Monument_-_01.jpg',
upvotes: 7,
comments:[
{body:'Seriously, not cost effective', upvotes:0},
],
},
{
title: 'Become more isolationist and bring our troops back home.',
avatar:'https://upload.wikimedia.org/wikipedia/commons/3/3b/Bunker_hill_2009.JPG',
upvotes: 3,
comments: [
{body:'sounds a little grim',upvotes:0}
],
}
]
};
return demoSuggestions;
}]);
If you look at the first two divs with the class row, you will notice, that the first div has a ng-controller attached (and displaying your title) and the second one has no controller attached (and displays nothing).
As your ng-repeat is not a child-element of your row with the controller, you cannot use your controller there. You could solve that if you move the ng-controller up one element so it will be on the parent of all your rows.

I can't scope anything onto my angular dialog(reviewForm) from the DialogController?

Below I have a button that is attached to each venue list item. So each list item has its own button. Also, each list item is a object. So when I click one of buttons I need to somehow grab the ID from that specific list item and be able to use it in my dialogcontroller.
<div class="results">
<div class="searchbox col-md-6 form-group">
<input type="text" placeholder="search venues" class="form-control" ng-model="filterTerm">
<ul class="list-unstyled">
<li class="well" ng-repeat="venues in venues | filter: filterTerm">
<h3>{{venues.name}}</h3>
<p>{{venues.info}}</p>
<md-button class="md-primary md-raised" ng-click="showAdvanced($event, venues)" flex-sm="100" flex-md="100" flex-gt-md="auto">Add a Review</md-button>
<button>See Reviews</button>
</li>
</ul>
</div>
My get call to my JSON file. Also, This is my ng-click function that is using mdDialog (which opens a popup window with a reviewForm.html as its content.
$http.get('/getMarkers').success(function(response) {
$scope.venues = response;
console.log($scope.venues);
});
$scope.showAdvanced = function(ev, venues){
$mdDialog.show({
controller: DialogController(ev,venues),
templateUrl: 'views/reviewForm.html',
parent:angular.element(document.body),
targetEvent: ev,
clickOutsideToClose:true
})
};
This is my DialogController which is handling the content(reviewForm.html) that is being rendered in my mdDialog window.
function DialogController($scope, venues, $mdDialog) {
console.log(venues);
$scope.rate = 0;
$scope.max = 5;
$scope.hoveringStaff = function (value) {
$scope.overStar = value;
$scope.percent = 100 * (value / $scope.max);
console.log($scope.overStar);
};
}
This is the html that is going into the dialog
<md-dialog aria-label="Review Form">
{{something}}
<md-toolbar>
{{venues}}
<div class="md-toolbar-tools">
<h2>Review Form</h2>
<span flex></span>
</div>
</md-toolbar>
<md-dialog-content>
{{$scope.something}}
<label>{{something}}Show Attended: </label><input type="text" ng-model="show"><br/>
<label>Date: </label><input type="date" ng-model="date"><br/>
<label>Staff Friendliest: </label><uib-rating ng-model="rate" max="max" on-hover="hoveringStaff(value)" on-leave="overStar = null" titles="['one','two','three']" aria-labelledby="default-rating"></uib-rating><br/>
<label>Sound Quality: </label><input type="text" ng-model="sound"><br/>
<label>Favorite Drink/Cocktail: </label><input type="text" ng-model="drink"><br/>
<label>Nearby Bar/Food Recommendations: </label><input type="text" ng-model="nearby"><br/>
<label>Comments: </label><input type="text" ng-model="comments"><br/>
<label>Venue Rating: </label><br/>
<md-button class="md-raised md-primary" ng-click="sendReview()">Primary</md-button>
</md-dialog-content>
I need the ID because I am going to posting a form to the database and need to add the form content to the selected list item. Sorry if this is confusing, let me know if you have any questions. Thanks!
I think you might need to use locals or resolve to pass objects to the new controllers, because of angular's dependency injection, passing objects to the controller will not work (i.e MyController($scope, a, b)).
ex:
$mdDialog.show({
locals: {
venue: venue
}
});
or with resolve
$mdDialog.show({
resolve: {
venue: function(){return venue;}
}
});
Another issue which I think is a typo, is in the ng-repeat directive venues in venues which should be venue in venues.
Reference the view values to venue object(i.e venue.drink, venue.date, ...ect) instead of $scope, will make it easier to pass it back to the parent controller.
function MainCtrl($http, $scope, $mdDialog) {
/*
$http.get('/getMarkers').success(function(response) {
$scope.venues = response;
console.log($scope.venues);
});
*/
$scope.venues = [{
name: 'Venue #1',
info: 'Info',
date: new Date(),
drink: 'A drink'
}];
$scope.showAdvanced = function(ev, venue) {
$mdDialog.show({
controller: 'DialogController',
template: '<md-dialog aria-label="Review Form">\
{{venue.name}}\
<md-toolbar>\
{{venue}}\
<div class="md-toolbar-tools">\
<h2>Review Form</h2>\
<span flex></span>\
</div>\
</md-toolbar>\
<md-dialog-content>\
{{venue.name}}\
<label>{{venue.name}}Show Attended: </label><input type="text" ng-model="venue.show"><br/>\
<label>Date: </label><input type="date" ng-model="venue.date"><br/>\
<label>Staff Friendliest: </label><uib-rating ng-model="venue.rate" max="max" on-hover="hoveringStaff(value)" on-leave="overStar = null" titles="[\'one\',\'two\',\'three\']" aria-labelledby="default-rating"></uib-rating><br/>\
<label>Sound Quality: </label><input type="text" ng-model="venue.sound"><br/>\
<label>Favorite Drink/Cocktail: </label><input type="text" ng-model="venue.drink"><br/>\
<label>Nearby Bar/Food Recommendations: </label><input type="text" ng-model="venue.nearby"><br/>\
<label>Comments: </label><input type="text" ng-model="venue.comments"><br/>\
<label>Venue Rating: </label><br/>\
<md-button class="md-raised md-primary" ng-click="sendReview()">Primary</md-button>\
</md-dialog-content>',
parent: angular.element(document.body),
targetEvent: ev,
clickOutsideToClose: true,
locals: {
venue: venue
}
})
};
}
function DialogController($scope, venue, $mdDialog) {
$scope.venue = venue;
console.log(venue);
$scope.rate = 0;
$scope.max = 5;
$scope.hoveringStaff = function(value) {
$scope.overStar = value;
$scope.percent = 100 * (value / $scope.max);
console.log($scope.overStar);
};
}
angular.module('MyApp', ['ngAria', 'ngAnimate', 'ngMaterial'])
.controller('MainCtrl', MainCtrl)
.controller('DialogController', DialogController);
<html>
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/angular-material/0.11.0/angular-material.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-material/0.11.0/angular-material.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular-animate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular-aria.min.js"></script>
</head>
<body ng-app="MyApp" ng-controller="MainCtrl">
<div class="results">
<div class="searchbox col-md-6 form-group">
<input type="text" placeholder="search venues" class="form-control" ng-model="filterTerm">
<ul class="list-unstyled">
<li class="well" ng-repeat="venue in venues | filter: filterTerm">
<h3>{{venue.name}}</h3>
<p>{{venue.info}}</p>
<md-button class="md-primary md-raised" ng-click="showAdvanced($event, venue)" flex-sm="100" flex-md="100" flex-gt-md="auto">Add a Review</md-button>
<button>See Reviews</button>
</li>
</ul>
</div>
</div>
</body>
</html>

rendering template html via backbone view

I have a simple page that contains a 3 step wizard. Basically, the user fills out a textbox, clicks next, which loads the next form field.
I have setup all the HTML inside a template and use that template in a backbone view.
The problem is, backbone isn't rendering the HTML inside the template. I just get a blank screen.
Here is my template:
<script type="text/template" id="assessmentTitleTemplate">
<div id="titleDiv">
<label for="title">Title:</label> <input type="text" />
</div>
<div id="choicesDiv" style="display: none;">
<label for="choices">Choices:</label><input type="text" />
</div>
<div id="typeDiv" style="display: none;">
<label for="types">Types:</label>
<select name="type">
<option>red</option>
<option>blue</option>
<option>green</option>
</select>
</div>
<div id="directionControl">
<input type="button" value="Prev" /> <input type="button" value="Next" />
</div>
</script>
This is my backbone javascript code:
"use strict";
var titleView = Backbone.View.extend({
tagName: 'div',
className: 'title',
template: _.template($('#assessmentTitleTemplate').html()),
events: {
'click .next': 'saveProceedNext',
'click .prev': 'ProceedPrev'
},
initialize: function () {
this.render;
},
render: function () {
this.$el.html(this.template(this.model.toJSON()));
return this;
},
saveProceedNext: function() {
this.$('#titleDiv').hide();
this.$('#choicesDiv').show();
},
ProceedPrev: function() {
}
});
Your code is correct, but you're missing a couple of parens in your initialize body:
initialize : function () {
this.render(); // it was this.render; before
}
Your code isn't invoking the function.
Also, you're missing class tags for your buttons, or else they won't work when clicked. Adding this will make them work:
<input type="button" value="Prev" class="prev" /> <input type="button" value="Next" class="next" />
Check this JSFiddle.

Backbone Marionette ItemView not firing event(using two templates)

I have a Backbone Marionette ItemView which has two template which i want to open on a specific condition.
Backbone view is registering events for 1 template, but not firing for second template.
var emailView = Marionette.ItemView.extend({
initialize: function(){
},
getTemplate: function(){
if(this.options.position == 'a'){
//load tempalte 2
return template2;
} else {
//load template 1
return template;
}
},
events: {
//event from second template, not firing
'click #abcdef': 'a',
//event from first template, working
'click #sendemail': 'b'
},
a: function(){
alert("Hello");
},
b: function(){
alert("Hellob");
}
When i run template 1, event are working fine, but when i load template2, its not taking events for it.
Can guide me what i am doing wrong.
My 1st template:
<div id="emaildialog" title="" class="emaild">
<div class="row">
<div class="row1">
<button class="k-button" id="sendemail">Send</button>
</div>
</div>
</div>
My 2nd template:
<div id="emailconfiguredialog" class="emaild" title="">
<div class="row">
<div class="row1">
<button class="k-button" id="abcdef">Update Email</button>
</div>
</div>
</div>

fetching data and show them in proper place in backbone

I have an issue in backbone, I want to render 100 rows of data from backend ( fetched by url) and show between of button element and pagination. I have created two templates, and have two views one for the whole page and the other for individual items. But when I fetch the data they do not go between the button and pagination div, all the 100 rows go under that. How can I put them in proper place? These are my templates:
the list template:
<div class="message-list-actions">
<div class="action">
<select>
<option value="0">Bulk Actions</option>
<option value="1">Delete</option>
<option value="2">Mark As Read</option>
</select>
<button class="grey">OK</button>
</div>
<div class="action">
<select>
<option value="0">All</option>
<option value="1">Unread Messages</option>
<option value="2">Read Messages</option>
</select>
<button class="grey">OK</button>
</div>
<div class="results right">
<form>
<label for="results">Results pr. page</label>
<select name="results">
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
<option value="500">500</option>
</select>
</form>
</div>
</div> <!-- message-list-actions -->
<div class="message-list">
<div class="message-list-header row">
<div class="left check">
<input type="checkbox" name="type"/>
<label for="type">CHECK ALL</label>
</div>
<div class="left date" >
<span class="sorter">Date</span>
</div>
<div class="large-9 columns" >
<span class="sorter">Message</span>
</div>
</div>
<section class="message-item row">
<div class="message-list"></div>
<div class="left check" >
<input type="checkbox" class="type">
</div>
<div class="left date" >
<div class="icon"></div>
</div>
<div class="large-9 columns" >
</div>
</section>
<section>
<ul class="pagination">
<li class="arrow unavailable">Previous</li>
<li class="current">1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li class="unavailable">…</li>
<li>12</li>
<li>13</li>
<li class="arrow">Next</li>
</ul>
</section>
other template:
<div class="message-list">
<section class="message-item row">
<div class="left check" >
<input type="checkbox" class="type">
</div>
<div class="left date" >
<p><%= created !== undefined ? created : "not available" %></p>
<div class="icon"></div>
<div class="severity normal"><%= name %></div>
</div>
<div class="large-9 columns" >
<h4><%= title %></h4>
<p><%= id %></p>
</div>
<!-- Delete -->
</section>
</div> <!-- .main -->
//view for message:
define([
"jquery",
"underscore",
"backbone",
"js/collections/messagesCollection",
"js/models/messagesModel",
"text!templates/messageView.html",
"text!templates/messageList.html",
"text!templates/messageDetails.html"
], function($, _ , Backbone,
MessagesCollection,
MessagesModel,
UserEditTemplate, UserViewTemplate, UserSelfEditTemplate, ResetPasswordTemplate, ChangePasswordTemplate){
MessageViewTemplate, MessageListTemplate, MessageDetailsTemplate){
var MessageView = Backbone.View.extend({
tagName : "div",
messageViewTemplate : _.template(MessageViewTemplate),
messageDetailsTemplate : _.template(MessageDetailsTemplate),
template : _.template(MessageDetailsTemplate),
collection : MessagesCollection,
initialize : function(){
this.model.on("change", this.render, this);
this.model.on("update", this.render, this);
},
render : function(){
//this.$el.html(this.userTemplate(this.model.toJSON()));
this.$el.html(this.messageViewTemplate(this.model.toJSON()));
return this;
}
});
return MessageView;
});
View for list of message:
define([
"jquery",
"underscore",
"backbone",
"js/models/loggedInUserModel",
"js/models/currentTabModel",
"js/models/messagesModel",
"js/collections/messagesCollection",
"js/views/messageView",
"text!templates/messageList.html",
"text!templates/messageDetails.html",
"text!templates/header.html",
"text!templates/breadcrumbs.html",
"text!templates/footer.html"
], function($, _, Backbone,
MessagesModel,
MessagesCollection,
MessageView,
MessageListTemplate, MessageDetailsTemplate, HeaderTemplate, BreadCrumbTemplate, FooterTemplate
){
var MessagesView = Backbone.View.extend({
el : $("#maincontent"),
messageListTemplate : MessageListTemplate,
messageDetailsTemplate : _.template(MessageDetailsTemplate),
collection : MessagesCollection,
initialize : function(){
console.log("initialize messages");
this.collection = new MessagesCollection();
this.collection.on("add", this.renderMessage, this);
this.collection.on("reset", this.render, this);
this.collection.on("update", this.render, this);
if(this.options.selfEdit === false || _.isUndefined(this.options.selfEdit)){
this.start();
}
else{
console.log("options", this.options);
this.currentUserModel.fetch();
}
},
start : function(){
this.collection.fetch();
this.currentUserModel.fetch();
this.renderFooter();
},
render : function(){
this.$el.html(this.messageListTemplate);
_.each(this.collection.models, function(item){
this.renderMessage(item);
}, this);
},
renderMessage : function(item){
var messageView = new MessageView({
model : item
});
this.$el.append(messageView.render().el);
},
renderMessageDetails : function(item){
var messageView = new MessagesView({
model : item
});
this.$el.append(messageView.renderSelfView().el);
}
});
return MessagesView;
});
//Model
define([
"jquery",
"underscore",
"backbone"
], function($, _ , Backbone){
var MessagesModel = Backbone.Model.extend({
defaults : {
id : null,
created : null,
timestamp : null,
severity : null
},
parse : function(response){
response.id = response._id.$oid;
response.created = response.created.$date;
response.timestamp = response.timestamp.$date;
response.severity = response.severity;
return response;
},
clear : function(){
this.destroy();
this.view.remove();
},
// Convert regular JSON into MongoDB extended one.
toExtendedJSON: function() {
var attrs = this.attributes;
attrs = _.omit(attrs, ["created", "timestamp"]);
if (_.isUndefined(attrs.created)) {
// console.log("this", this["this.created"]);
attrs.created = { $date: this.get("created") };
}
if (_.isUndefined(attrs.timestamp)) {
attrs.timestamp = { $date: this.get("timestamp") };
}
console.dir(attrs);
return attrs;
},
// Substute toJSON method when performing synchronization.
sync : function(method, model, options) {
/*
* If we are performing an update we need to call the extendedJSON method
* By calling this, we guarantee that we comply to the MongoDB model.
* After applying that model, we then call Backbone .sync protoryp and then set the model.toJSON method
* back to its original definition.
*/
if(method === "update" && !model.isNew()){
var toJSON = this.toJSON;
this.toJSON = this.toExtendedJSON;
var ret = Backbone.sync.apply(this, arguments);
this.toJSON = toJSON;
return ret;
}
else{
return Backbone.sync.call(this, method, this, options);
}
},
formatDate : function(dateString) {
return new Date(dateString).toUTCString();
}
});
return MessagesModel;
});
Collection
define([
"jquery",
"underscore",
"backbone",
"js/models/messagesModel"
],function($,_, Backbone, MessagesModel){
var MessagesCollection = Backbone.Collection.extend({
model : MessagesModel,
url : "/api/v1/message",
parse : function(response, xhr){
return response.list;
}
});
return MessagesCollection;
});
Try following for renderMessage():
renderMessage : function(item){
var messageView = new MessageView({
model : item
});
this.$el.find('div.message-list').append(messageView.render().el);
},
Also update the code in a similar way for renderMessageDetails().

Resources