var HandlebarsView = Backbone.View.extend({
render: function() {
if (!_.isFunction(this.template)) {
this.tmpl = Handlebars.compile(this.tmpl);
}
this.$el.html(this.tmpl(this.model || this.collection || {}));
return this;
}
});
var TaskView = HandlebarsView.extend({
render: function() {
console.log('Rendering...');
TaskView.__super__.render.apply(this);
}
});
var Task = Ember.Object.extend({
done: false,
init: function() {
this.createdAt = new Date();
},
createdSince: function() {
return moment(this.get('createdAt')).fromNow();
}.property('createdAt')
});
var User = Ember.Object.extend({
remainingTasks: function() {
return this.get('tasks').filterProperty('done', false)
.get('length');
}.property('tasks.@each.done')
});
var task1 = Task.create({title: 'Go to Mix-IT'});
task1.set('done', true);
console.log(task1.get('summary'));
var task2 = Task.create({title: 'Enjoy the party!'});
console.log(task2.get('summary'));
var user = User.create();
user.set('tasks', [task1, task2]);
console.log('Remaining: ' + user.get('remainingTasks'));
module.factory('Task', ['$resource', function($resource) {
return $resource('http://localhost\\:3000/tasks/:id', {}, {
query: {method: 'GET', isArray: false}
});
}]);
var TasksCtrl = ['$scope', 'Task', function($scope, Task) {
Task.query({}, function(response) {
$scope.tasks = response.tasks;
});
}];
var Task = Backbone.Model.extend({
defaults: {
title: 'New Task'
}
});
render: function() {
return this;
}
var HandlebarsView = Backbone.View.extend({
render: function() {
if (!_.isFunction(this.template)) {
this.tmpl = Handlebars.compile(this.tmpl);
}
this.$el.html(this.tmpl(this.model||this.collection||{}));
return this;
}
});
var TaskFormView = HandlebarsView.extend({
template: $('#task-form-template').html(),
events: {
'submit form': 'save'
},
save: function() {
this.model.save({
title: this.$('#title').val(),
description: this.$('#description').val()
}, {
success: _.bind(function() {
Backbone.history.navigate("#task/" +
this.model.get('id'), true);
}, this)
});
return false;
}
});
<ul>
{{#each task in model}}
<li {{bindAttr class="task.active:active"}}>
<h1>
{{#linkTo "tasks.show" task}}{{task.title}}{{/linkTo}}
</h1>
</li>
{{/each}}
<li>{{#linkTo "tasks.new"}}New task...{{/linkTo}}</li>
</ul>
<ul>
<li ng-repeat="task in tasks"
ng-class="{active: task.active}">
<h1><a href="#/tasks/{{task.id}}">{{task.title}}</a></h1>
</li>
<li><a href="#/tasks/new">New task...</a></li>
</ul>
var TaskDetailsCtrl = ['$scope', '$routeParams', 'Task',
function($scope, $routeParams, Task) {
var task = Task.get({id: $routeParams.taskId},
function(response) {
$scope.task = response.task;
Task.active($scope.task);
}
);
}
];
<h1>{{task.title}}</h1>
<p>{{task.description}}</p>
var PromptView = Backbone.View.extend({
events: { keyup: 'change' },
render: function() {
this.$el.html('<input id="name" type="text" />');
return this;
},
change: function() {
this.model.set('name', this.$('#name').val());
}
});
var HelloView = Backbone.View.extend({
initialize: function() {
this.listenTo(this.model, 'change', this.render);
},
render: function() {
this.$el.html('Hello ' + (this.model.get('name') || ''));
return this;
}
});
<ul>
<script id="metamorph-0-start"></script>
<script id="metamorph-2-start"></script>
<li class="active" data-bindattr-1="1">
<h1>
<a id="ember378" class="active" href="#/tasks/1">
<script id="metamorph-4-start"></script>
Task1
<script id="metamorph-4-end"></script>
</a>
</h1>
</li>
<script id="metamorph-2-end"></script>
<script id="metamorph-3-start"></script>
<li class="" data-bindattr-2="2">...</li>
<script id="metamorph-3-end"></script>
<script id="metamorph-0-end"></script>
<li>...</li>
</ul>
var AppView = Ember.View.extend({
template: $('#ember-binding-template').html()
});
<div>{{input value="name"}}</div>
<div>Hello {{name}}!</div>
<div ng-app>
<div><input type="text" ng-model="name" /></div>
<div>Hello {{name}}!</div>
</div>
Associate an URL to a particular application state
Managing Single Page Application layouts?
var TasksRouter = Backbone.Router.extend({
routes: {
'': 'index',
'tasks': 'list',
'task/new': 'create',
'task/:id': 'show',
'task/:id/edit': 'edit',
'task/:id/remove': 'remove'
},
// ....
});
show: function(id) {
this.current(TaskDetailsView, id);
}
current: function(viewClass, task) {
if (!(task instanceof Task)) {
var id = task;
task = this.tasks.get(id);
if (!task) {
alert('The task with id ' + id + ' does not exist.');
return this.navigate('#tasks', true);
}
}
this.list();
this.active(task);
this.currentView = new viewClass({model: task});
$('.task').html(this.currentView.render().el);
}
list: function() {
if (!this.tasksView||this.tasksView.$el.parent().size()===0) {
this.tasksView = new TasksView({collection: this.tasks});
$('#app').html(this.tasksView.render().el);
}
if (this.currentView) {
this.currentView.remove();
}
this.active();
}
Tasks.Router.map(function() {
this.resource('tasks', function() {
this.route('new', { path: '/new' });
this.route('show', { path: '/:task_id' });
this.route('edit', { path: '/:task_id/edit' });
this.route('remove', { path: '/:task_id/remove' });
});
});
<div class="tasks">
<ul>
{{#each task in model}}
<li {{bindAttr class="task.active:active"}}>
<h1>
{{#linkTo "tasks.show" task}}
{{task.title}}
{{/linkTo}}
</h1>
</li>
{{/each}}
<li>{{#linkTo "tasks.new"}}New task...{{/linkTo}}</li>
</ul>
</div>
{{outlet}}
Tasks.TasksNewRoute = Ember.Route.extend({
renderTemplate: function() {
this.render('tasks/form');
},
model: function() {
return Tasks.Task.createRecord({
title: 'New Task',
description: 'Desc'
});
},
setupController: function(controller, task) {
Tasks.Task.active(task);
controller.set('content', task);
},
events: {
save: function(task) {
task.one('didCreate', this, function() {
this.transitionTo('tasks.show', task);
});
this.get('store').commit();
}
}
});
$routeProvider.
when('/tasks', {
templateUrl: 'partials/tasks.html',
controller: TasksCtrl
}).
when('/tasks/:taskId', {
templateUrl: 'partials/tasks.html',
controller: TasksCtrl,
nested: {
templateUrl: 'partials/task-details.html',
controller: TaskDetailsCtrl
}
}).
// ...
otherwise({redirectTo: '/tasks'});
var Tasks = Backbone.Collection.extend({
model: Task,
url: 'http://localhost:3000/tasks',
parse: function(response) {
return response.tasks;
}
});
save: function() {
this.model.save({
title: this.$('#title').val(),
description: this.$('#description').val()
}, {
success: _.bind(function() {
Backbone.history.navigate("#task/" + this.model.get('id'), true);
}, this)
});
return false;
}
save: function(task) {
task.one('didCreate', this, function() {
this.transitionTo('tasks.show', task);
});
this.get('store').commit();
}
module.factory('Task', ['$resource', function($resource) {
var resource = $resource('http://localhost\\:3000/tasks/:id', {}, {
query: {method: 'GET', isArray: false}
});
]);
var TaskNewCtrl = ['$scope', '$location', 'Task',
function($scope, $location, Task) {
var task = new Task({
title: 'New Task',
description: 'Desc'
});
$scope.task = task;
$scope.save = function() {
this.task.$save(function(t) {
$location.path('/tasks/' + t.id);
});
};
}
];
<form {{action save model on="submit"}}>
<div>
{{input value="title" placeholder="Title"}}
</div>
<div>
{{textarea value="description" placeholder="Description"}}
</div>
...
</form>