所属分类:web前端开发
在上一届会议中,您重构了整个博客系统。现在一切都已清理干净,您已准备好加速进行一些新的冒险。在本次会议中,我们将围绕路由器做更多的事情,并向我们的博客系统添加三个功能:删除、注销和单个博客视图。
在第 6 部分中,我们介绍了编辑功能。您很可能还想删除您的一篇博客文章。有两个地方可以放置此函数:将其添加到 BlogsAdminView
中,或者将其发送到 URL 并在 Router
中处理。
我将向您展示路由器的方式。它更常用,并且使代码更加结构化。
像往常一样,我们先添加一个 URL 模式:
routes: { '': 'index', 'admin': 'admin', 'login': 'login', 'add': 'add', 'edit/:id': 'edit', 'del/:id': 'del' }
然后,更新管理页面中的链接:
Delete
现在,让我们向 Router 添加一个新的 del
函数来处理它。这非常简单:使用我们从 URL 传入的 id
找到博客文章,并将其销毁。
尝试挑战自己,在不阅读我的代码的情况下编写它。此时您应该已经很好地掌握了 Parse.js。
del: function(id) { var query = new Parse.Query(Blog); query.get(id).then(function(blog){ blog.destroy().then(function(blog){ alert('Deleted!'); }) }); }
请注意,您可以在此处使用 .then()
函数,而不是像我们之前那样传递对象:
query.get(id, { success: function(blog) { ... }, error: function(blog, error) { ... } });
这是在 Parse.js 中添加回调函数的简单方法,使您的代码更干净、更具可读性。请访问 Parse.com 查看有关 Promise 的完整文档。
让我们对其进行测试运行,并仔细检查数据库以查看它是否正常工作。
恭喜,它正在工作!
如果你注意一下URL,你会发现,点击掉警告框后,URL仍然是/del/
,而你刚刚删除的帖子仍然存在。我们希望在删除后将用户发送回管理页面,并且该页面应该刷新并反映他们刚刚所做的更改。
您可以通过重定向来实现所有这些:
del: function(id) { var self = this, query = new Parse.Query(Blog); query.get(id).then(function(blog){ blog.destroy().then(function(blog){ self.navigate('admin', { trigger: true }); }) }); }
请注意,因为这次您从路由器内部调用 navigate
,所以您可以将路由器存储为 self
,然后调用 self.navigate()
。
最后,我们需要确保您是唯一可以删除您的博客帖子的人。让我们检查一下该功能的登录。这应该与 edit
函数相同。
del: function(id) { if (!Parse.User.current()) { this.navigate('#/login', { trigger: true }); } else { ... } }
与删除一样,注销也可以由路由器处理。它还从添加 URL 模式开始:
routes: { ... 'logout': 'logout' },
Parse.js 中的注销功能本身非常简单。只需调用 Parse.User.logOut()
,然后重定向到 /login
页面:
logout: function () { Parse.User.logOut(); this.navigate('#/login', { trigger: true }); }
最后,让我们向 #admin-tpl
添加一个按钮:
Logout
如您所见,样式确实不是本教程的重点。您可以随意修复填充并根据需要设置样式。
现在让我们继续开发一些新功能。
到目前为止,我们正在主页上显示整篇博客文章。虽然有些人确实喜欢这种风格,但大多数博客系统都支持预先提供片段摘要的想法,如果访问者点击文章,他们就可以在单独的页面上看到内容,周围可能还有一些评论区域。
我将在本次会议中引导您创建这个详细的单一博客视图,我们将在下一次会议中重点关注构建评论。
首先,我们在博客表中添加一列作为摘要:
现在,让我们将其添加到 Blog.update()
函数中。您可以更改该函数以获取包含标题、摘要和内容的数据对象,以避免记住变量的顺序。
update: function(data) { // Only set ACL if the blog doesn't have it ... this.set({ 'title': data.title, 'summary': data.summary, 'content': data.content, ... }).save(null, { ... }); }
在#write-tpl
中再添加一个<textarea>
作为摘要:
// Put this form-group in between the form-group for title and content Summary {{summary}}
并相应地更改 WriteBlogView.submit()
函数:
submit: function(e) { ... this.model.update({ title: data[0].value, summary: data[1].value, content: data[2].value }); }
现在,由于我们在模板中添加了一个新变量,因此我们需要在 WriteBlogView.render()
函数中为其指定一个默认的空值:
render: function(){ ... if (this.model) { ... } else { attributes = { form_title: 'Add a Blog', title: '', summary: '', content: '' } } ... }
如果您对内容使用 wysihtml5 插件,您会注意到之前我们的目标是所有 <textarea>
元素:
this.$el.html(this.template(attributes)).find('textarea').wysihtml5();
让我们为内容文本区域指定一个类,并仅使用 wysihtml5 插件来定位该类。
在#write-tpl
中:
{{{content}}}
在WriteBlogView.render()
函数中:
this.$el.html(this.template(attributes)).find('.write-content').wysihtml5();
现在可以使用了!
使用新的撰写博客页面并添加一些带有摘要的博客文章,并提取摘要而不是#blogs-tpl
中的内容:
{{#each blog}} {{title}} At {{time}} by {{authorName}} {{summary}} {{/each}}
花一点时间考虑一下如何添加 /blog/:id
页面来显示每篇博客文章的内容,并尝试自己完成。您现在应该能够自己完成这一切了!
但为了本教程的目的,让我给您快速演练:
为此页面添加新的 HTML 模板:
<div class="blog-post"> <h2 class="blog-post-title">{{title}}</h2> <p class="blog-post-meta">At {{time}} by {{authorName}}</p> <div>{{{content}}}</div> </div>
添加一个新的 BlogView
类,该类接受 blog
对象,并将其呈现在 #blog-tpl
中: p>
BlogView = Parse.View.extend({ template: Handlebars.compile($('#blog-tpl').html()), render: function() { var attributes = this.model.toJSON(); this.$el.html(this.template(attributes)); } }),
在 BlogRouter
中添加新的 URL 模式:
routes: { ... 'blog/:id': 'blog', ... }
并在 BlogRouter.blog()
函数中,通过 id 获取博客,渲染一个 blogView
,并将其放入 $container
:
blog: function(id) { var query = new Parse.Query(Blog); query.get(id, { success: function(blog) { console.log(blog); var blogView = new BlogView({ model: blog }); blogView.render(); $container.html(blogView.el); }, error: function(blog, error) { console.log(error); } }); }
最后,更新#blogs-tpl
中的链接以链接到此页面:
{{#each blog}} {{title}} At {{time}} by {{authorName}} {{summary}} {{/each}}
尝试一下:
如果您自己完成此操作,可加分。
在本次会议中,您构建了很多内容:删除功能、注销功能和另一种新页面类型。如果您到目前为止一直在关注本教程系列,我认为您对数据库、模型、视图、模板和路由器如何协同工作有深入的了解。我希望您现在也开始喜欢构建 Parse.js 项目。请留下您的反馈并告诉我是否有帮助。
通过我们这次构建的这个单一博客文章页面,我们下次将添加评论部分。应该是一件有趣的事。敬请关注!</textarea></textarea>