Skip to content

Commit 87b8d71

Browse files
committed
Post GRUD is now supported
1 parent 5774fab commit 87b8d71

File tree

20 files changed

+406
-36
lines changed

20 files changed

+406
-36
lines changed

app.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@
44

55
var express = require('express')
66
, mongoose = require('mongoose')
7-
, http = require('http');
7+
, http = require('http')
8+
, config = require('./config');
89

910
var app = express();
1011

12+
mongoose.connect('mongodb://localhost/' + config.DB_NAME);
13+
1114
app.configure(function(){
1215
app.set('port', process.env.PORT || 3000);
1316
app.use(express.favicon());

config.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1-
exports = {
2-
API: '/api/v1'
1+
module.exports = {
2+
DB_NAME: 'backbone-sample-blog'
3+
, API: '/api/v1'
34
};

models/schemas.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ var PostSchema = new Schema({
66
title: String
77
, author: String
88
, body: String
9-
, creataAt: {
9+
, date: {
1010
type: Date
1111
, default: Date.now
1212
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
define('PostCollection', [
2+
'jquery'
3+
, 'underscore'
4+
, 'backbone'
5+
, 'PostModel'
6+
], function ($, _, backbone, PostModel) {
7+
var PostClooection;
8+
9+
PostCollection = backbone.Collection.extend({
10+
model: PostModel
11+
, url: '/api/v1/post/list'
12+
});
13+
14+
return PostCollection;
15+
});

public/javascripts/main.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,14 @@ requirejs.config({
2020
, jquery : 'lib/jquery'
2121
, underscore : 'lib/underscore-amd'
2222
, backbone : 'lib/backbone-amd'
23+
, PostModel : 'models/post'
24+
, PostCollection : 'collections/post'
2325
, HeaderView : 'views/header'
2426
, HomeView : 'views/home'
27+
, PostAddView : 'views/post/add'
28+
, PostShowView: 'views/post/show'
29+
, PostListView: 'views/post/list'
30+
, PostEditView: 'views/post/edit'
2531
}
2632
});
2733

public/javascripts/models/post.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
define('PostModel', [
2+
'jquery'
3+
, 'underscore'
4+
, 'backbone'
5+
], function ($, _, backbone) {
6+
var Post;
7+
8+
Post = backbone.Model.extend({
9+
idAttribute: '_id'
10+
, urlRoot: '/api/v1/post'
11+
, defaults: {
12+
title: ''
13+
, author: ''
14+
, body: ''
15+
, date: new Date()
16+
}
17+
, validate: function (attrs) {
18+
}
19+
});
20+
21+
return Post;
22+
});

public/javascripts/router.js

Lines changed: 92 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,29 @@ define('router', [
22
'jquery'
33
, 'underscore'
44
, 'backbone'
5+
, 'PostModel'
56
, 'HomeView'
67
, 'HeaderView'
7-
//, 'PostListView'
8-
//, 'PostView'
9-
//, 'PostEditView'
10-
//, 'PostModel'
11-
//], function ($, _, backbone, HomeView, HeaderView, PostListView, PostView, PostEditView, Post) {
12-
], function ($, _, backbone, HomeView, HeaderView) {
8+
, 'PostAddView'
9+
, 'PostShowView'
10+
, 'PostListView'
11+
, 'PostEditView'
12+
], function ($, _, backbone, Post, HomeView, HeaderView, PostAddView, PostShowView, PostListView, PostEditView) {
1313
var router;
1414

1515
router = backbone.Router.extend({
1616
routes: {
1717
'' : 'home'
1818
, 'home' : 'home'
19-
, 'posts' : 'showPosts'
20-
, 'posts/new' : 'addPost'
21-
, 'posts/:id' : 'showPost'
22-
, 'posts/:id/edit' : 'editPost'
19+
, 'post/list' : 'showPostList'
20+
, 'post/new' : 'addPost'
21+
, 'post/:id' : 'showPost'
22+
, 'post/:id/edit' : 'editPost'
2323
, '*action' : 'defaultAction'
2424
}
2525
, initialize: function () {
26-
this.postView = {};
27-
this.postEditView = {};
26+
this.postListView;
27+
this.postAddView;
2828
this.headerView = new HeaderView();
2929

3030
// cached elements
@@ -42,6 +42,86 @@ define('router', [
4242
}
4343
this.elms['page-content'].html(this.homeView.render().el);
4444
}
45+
, showPostList: function () {
46+
var that = this;
47+
48+
if (!this.postListView) {
49+
this.postListView = new PostListView();
50+
}
51+
this.postListView.render(function () {
52+
that.elms['page-content'].html(that.postListView.el);
53+
});
54+
55+
}
56+
, showPost: function (id) {
57+
var that, view, model;
58+
that = this;
59+
60+
// set silent to bypass the validation for fetching
61+
model = new Post({
62+
_id: id
63+
, silent: true
64+
});
65+
model.fetch({
66+
success: function (model, res) {
67+
view = new PostShowView({ model: model });
68+
that.elms['page-content'].html(view.render().el);
69+
70+
view.model.on('delete-success', function () {
71+
delete view;
72+
that.navigate('#/post/list', { trigger: true });
73+
});
74+
}
75+
, error: function (model, res) {
76+
// TODO
77+
}
78+
});
79+
}
80+
, addPost: function () {
81+
var that = this, view;
82+
83+
view = new PostAddView({
84+
model: new Post()
85+
});
86+
87+
this.elms['page-content'].html(view.render().el);
88+
view.on('back', function () {
89+
delete view;
90+
that.navigate('#/post/list', { trigger: true });
91+
});
92+
view.model.on('add-success', function (id) {
93+
delete view;
94+
that.navigate('#/post/' + id, { trigger: true });
95+
});
96+
}
97+
, editPost: function (id) {
98+
var that, view, post;
99+
100+
that = this;
101+
102+
post = new Post({
103+
_id: id
104+
, silent: true
105+
});
106+
post.fetch({
107+
success: function (model, res) {
108+
view = new PostEditView({ model: model });
109+
that.elms['page-content'].html(view.render().el);
110+
111+
view.on('back', function () {
112+
delete view;
113+
that.navigate('#/post/' + id, { trigger: true });
114+
});
115+
view.model.on('save-success', function () {
116+
delete view;
117+
that.navigate('#/post/' + id, { trigger: true });
118+
});
119+
}
120+
, error: function (model, res) {
121+
// TODO
122+
}
123+
});
124+
}
45125
});
46126

47127
return router;
Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
<div id="nav-bar">
2-
<ul>
3-
<li id="nav-home"><a href="#/home">首頁</a></li>
4-
<li id="nav-post-list"><a href="#/posts/list">顯示全部</a></li>
5-
<li id="nav-add-post"><a href="#/posts/new">新增</a></li>
6-
</ul>
7-
</div>
1+
<ul id="header-nav-bar">
2+
<li id="header-nav-home"><a href="#/home">首頁</a></li>
3+
<li id="header-nav-post-list"><a href="#/post/list">顯示全部</a></li>
4+
<li id="header-nav-add-post"><a href="#/post/new">新增</a></li>
5+
</ul>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<label for="post-add-title">標題</label>
2+
<input type="text" name="title" id="post-add-title" />
3+
<br />
4+
<label for="post-add-author">作者</label>
5+
<input type="text" name="author" id="post-add-author" />
6+
<br />
7+
<label for="post-add-body">內容</label>
8+
<textarea name="body" id="post-add-body"></textarea>
9+
<br />
10+
<button id="post-add-back">返回</button>
11+
<input type="submit" id="post-add-submit" />
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<label for="post-edit-title">標題</label>
2+
<input type="text" name="title" id="post-edit-title" value="<%= post.title %>"/>
3+
<br />
4+
<label for="post-edit-author">作者</label>
5+
<input type="text" name="author" id="post-edit-author" value="<%= post.author %>"/>
6+
<br />
7+
<label for="post-edit-body">內容</label>
8+
<textarea name="body" id="post-edit-body"><%= post.body %></textarea>
9+
<br />
10+
<button id="post-edit-back">返回</button>
11+
<button id="post-edit-save">儲存</button/>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<% _.each(posts, function (post) { %>
2+
<div class="post">
3+
<h4 class="post-title"><a href="#/post/<%= post._id %>"><%= post.title %></a></h4>
4+
<p class="post-author"><%= post.author %></p>
5+
<p class="post-body"><%= post.body %></p>
6+
</div>
7+
<% }); %>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<h3 class="post-show-title"><%= post.title %></h3>
2+
<p class="post-show-author"><%= post.author %></p>
3+
<p class="post-show-body"><%= post.body %></p>
4+
<a href="#/post/<%= post._id %>/edit">編輯</a>&nbsp;|&nbsp;<span class="link post-show-delete">刪除</span>

public/javascripts/views/header.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ define('HeaderView', [
77
var HeaderView;
88

99
HeaderView = backbone.View.extend({
10-
initialize: function () {
10+
id: 'header-view'
11+
, initialize: function () {
1112
var ajaxLoader;
1213

13-
this.template = _.template(tpl);
14+
this.compiled = _.template(tpl);
1415

1516
$('body').ajaxStart(function () {
1617
ajaxLoader = ajaxLoader || $('#ajax-loader');
@@ -20,7 +21,7 @@ define('HeaderView', [
2021
});
2122
}
2223
, render: function () {
23-
this.$el.html(this.template());
24+
this.$el.html(this.compiled());
2425
return this;
2526
}
2627
});

public/javascripts/views/home.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ define('HomeView', [
88

99
HomeView = backbone.View.extend({
1010
initialize: function () {
11-
this.template = _.template(tpl);
11+
this.compiled = _.template(tpl);
1212
}
1313
, render: function () {
14-
this.$el.html(this.template());
14+
this.$el.html(this.compiled());
1515
return this;
1616
}
1717
});

public/javascripts/views/post/add.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
define('PostAddView', [
2+
'jquery'
3+
, 'underscore'
4+
, 'backbone'
5+
, 'text!templates/post/add.html'
6+
], function ($, _, backbone, tpl) {
7+
var PostAddView;
8+
9+
PostAddView = backbone.View.extend({
10+
id: 'post-add-view'
11+
, initialize: function () {
12+
this.compiled = _.template(tpl);
13+
}
14+
, render: function () {
15+
this.$el.html(this.compiled());
16+
return this;
17+
}
18+
, events: {
19+
'click #post-add-submit': 'addPost'
20+
, 'click #post-add-back': 'back'
21+
}
22+
, addPost: function (e) {
23+
var title, author, body, that;
24+
25+
e.preventDefault();
26+
27+
that = this;
28+
title = $.trim($('#post-add-title').val());
29+
author = $.trim($('#post-add-author').val());
30+
body = $.trim($('#post-add-body').val());
31+
32+
this.model.save({
33+
title : title
34+
, author : author
35+
, body : body
36+
}, {
37+
silent : false
38+
, sync : true
39+
, success : function (model, res) {
40+
if (res && res.error) {
41+
// TODO
42+
} else {
43+
model.trigger('add-success', model.get('_id'));
44+
}
45+
}
46+
, error: function (model, res) {
47+
// TODO
48+
}
49+
});
50+
}
51+
, back: function (e) {
52+
e.preventDefault();
53+
this.trigger('back');
54+
}
55+
});
56+
57+
return PostAddView;
58+
});

0 commit comments

Comments
 (0)