Nodejs之MEAN栈开发(二)----视图与模型
上一节做了对Express做了简单的介绍,提出了controller,介绍了路由。这一节将重点放到视图和模型上,完成几个静态页面并部署到heroku上。
导航
前端布局使用bootstrap,从官网下载后置于public文件夹下。打开layout.jade 先做一个导航.
doctype html
html
head
meta(name='viewport', content='width=device-width, initial-scale=1.0')
title= title
link(rel='stylesheet', href='/bootstrap/css/bootstrap.css')
link(rel='stylesheet', href='/stylesheets/style.css')
body
nav.navbar.navbar-default.navbar-fixed-top.navbar-inverse
.container
.navbar-header
a.navbar-brand(href='/') ReadingClub .collapse.navbar-collapse
ul.nav.navbar-nav.pull-right
li
a(href='/') 首页
li
a(href='/Books') 读物
li
a(href='/About') 关于
li
a(href='/Register') 注册
li
a(href='/Login') 登录
#bodycontent.container
block content footer.container
.row
.col-xs-12
small © stoneniqiu 2016 script(src='/javascripts/jquery-1.11.1.min.js')
script(src='/bootstrap/js/bootstrap.min.js')
block content 上文有介绍,可以理解成一个占位符。因为现在还用不惯stylus,就直接写css了,这样vs还有智能提示。
style.css
body {
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
background: gainsboro;
}
a {
color: #00b7ff;
}
.navbar-default {
background-color: #444;
border-color: black;
}
.navbar-default .navbar-nav > li > a:hover, .navbar-default .navbar-nav > li > a:focus {
color: #ffffff;
background-color:#222;
}
.navbar-default .navbar-nav > li > a{
color: #ccc;
}
a.navbar-brand{color: #fff !important}
运行起来,看到导航条

如果访问注册和登录,因为之前没有设置相应的页面就会报404。

app.use(function (req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
回头看layout.jade 没有一个html标签,直接是元素名或者样式名称开始,这种写法和sublime中写html相似,属性写在括号里,文字内容用空格隔开。元素的嵌套关系 通过严格的缩进来控制,这样的好处是代码量更少,层次更分明,但是代码一长,很不容易判断缩进的准确位置,没对齐很容易造成意外的嵌套。我现在的经验是从左往右的编写,而不是从上往下编写。也就是说,用jade写html的时候,先写好最外层的元素,然后在逐步写里面的子元素。而不是从上往下一个一个的写,这样就会出现缩进来带的困扰。
模型与视图
回到home.js,我们用JavaScript建立一个books模型,包含title,info,rating,img和tags。因为还没有使用数据库,这里直接创建。
books:
var books = [
{
id: 0,
title: "深入浅出Node.js",
info: "朴灵 / 人民邮电出版社 / 2013-12-1 / CNY 69.00",
rating: 5,
img: "https://img3.doubanio.com/mpic/s27269296.jpg",
tags: ["node", "深入浅出"],
brief: '本书从不同的视角介绍了 Node 内在的特点和结构。由首章Node 介绍为索引,涉及Node 的各个方面,主要内容包含模块机制的揭示、异步I/O 实现原理的展现、异步编程的探讨、内存控制的介绍、二进制数据Buffer 的细节、Node 中的网络编程基础、Node 中的Web 开发、进程间的消息传递、Node 测试以及通过Node 构建产品需要的注意事项。最后的附录介绍了Node 的安装、调试、编码规范和NPM 仓库等事宜。本书适合想深入了解 Node 的人员阅读。'
,ISBN: 9787115335500
},
{
id: 1,
title: "程序员修炼之道 : 从小工到专家",
info: "Andrew Hunt、David Thomas / 马维达 / 电子工业出版社 / 2005-1 / 48.00元",
rating: 5,
img: "https://img3.doubanio.com/mpic/s3957863.jpg",
tags: ["程序人生", "软件开发"],
brief: '《程序员修炼之道》由一系列的独立的部分组成,涵盖的主题从个人责任、职业发展,直到用于使代码保持灵活、并且易于改编和复用的各种架构技术。利用许多富有娱乐性的奇闻轶事、有思想性的例子以及有趣的类比,全面阐释了软件开发的许多不同方面的最佳实践和重大陷阱。无论你是初学者,是有经验的程序员,还是软件项目经理,本书都适合你阅读。'
,ISBN: 9787505397194
},
{
id: 2,
title: "Getting MEAN with Mongo, Express, Angular, and Node",
info: "Simon Holmes / Manning Publications / 2015-11-26 / USD 44.99",
rating: 4,
img: "https://img3.doubanio.com/mpic/s27676844.jpg",
tags: ["node", "web开发", "编程"],
brief: 'MEAN栈开发,比较详尽的的应用开发书籍'
, ISBN: 9781617292033
}
];
res.render('books', { title: 'Books', books: books }); jade
模型其实就是一个json对象,接下来我们修改books页面的布局。这里用左右布局,稍加调整
extends layout block content
.row
.col-md-9.page
each book in books
.row.booklist
.col-md-2
img(src='#{book.img}')
.col-md-10
p
a(href="/Detail/#{book.id}")=book.title
p=book.info
p
- for (var i = 1; i <= book.rating; i++)
span.glyphicon.glyphicon-star
- for (i = book.rating; i < 5; i++)
span.glyphicon.glyphicon-star-empty p.tags
each tag in book.tags
span=tag .col-md-3
.userinfo
p stoneniqiu
res.render('books', { title: 'Books', books: books });
在home.js中加入books,模型其实就是一个json对象,接下来我们修改books页面的布局。这里用左右布局,稍加调整,
extends layout block content
.row
.col-md-9.page
each book in books
.row.booklist
.col-md-2
img(src='#{book.img}')
.col-md-10
p
a(href="/Detail/#{book.id}")=book.title
p=book.info
p
- for (var i = 1; i <= book.rating; i++)
span.glyphicon.glyphicon-star
- for (i = book.rating; i < 5; i++)
span.glyphicon.glyphicon-star-empty p.tags
each tag in book.tags
span=tag .col-md-3
.userinfo
p stoneniqiu
得到效果:

当然这些都还是静态的,接下来介绍下jade引擎。jade是一个高性能的模板引擎,用于node。
1.母版页
借助bootstrap的栅栏布局,分成左右两部分。extends layout 表示引入layout母版页,而layout中的block content 就会被当前页面的block content中的内容替换掉。同样可 以定义多个block
//- layout.jade
doctype html
html
head
block title
title Default title
body
block content
引用页面:
//- index.jade
extends layout block title
title Article Title block content
h1 My Article
生成的html:
<!doctype html>
<html>
<head>
<title>Article Title</title>
</head>
<body>
<h1>My Article</h1>
</body>
</html>
2.循环
each book in books
表示循环输出模型,在Asp.net MVC的视图中,需要先定义Model的类型。jade省掉了这个model,直接获取模型的属性。同样也支持for循环,前面的‘-’号不可少。
- for (var i = 1; i <= book.rating; i++)
span.glyphicon.glyphicon-star
- for (i = book.rating; i < 5; i++)
span.glyphicon.glyphicon-star-empty
3.赋值
空格赋值,这个空格不能少,不然jade会把ptext视为一个元素。空格后方都认为是字符串。
p text 输出 <p>text<p>
所以如果是输出变量,一定要用‘=’赋值。
a(href="/Detail/")=book.title
但如果是字符串组合输入,应该用#{}
img(src='#{book.img}')
p 读过#{book.title}
如果不想转义内容 !{},- var 表示定义变量 ,相当于Razor中的@{}
- var riskyBusiness = "<em>Some of the girls are wearing my mother's clothing.</em>";
.quote
p Joel: !{riskyBusiness}
输出
<div class="quote">
<p>Joel: <em>Some of the girls are wearing my mother's clothing.</em></p>
</div>
4.属性
如果是增加元素属性,则更在元素后面的括号里完成
a(href="/Detail/")=book.title
输出:
<a href="/Detail/">深入浅出Node.js</a>
如果是多个属性用逗号隔开,也可以换行
a(class='button', href='google.com')
input(
type='checkbox'
name='agreement'
checked
)
还可以加入表达式
- var authenticated = true
body(class=authenticated ? 'authed' : 'anon')
而Razor要在元素里面写表达式就有点丑陋。
@{
var ischeck = true;
}
<input type="checkbox" @if (ischeck)
{
@Html.Raw("class='selected'")
}
/>
5.子视图
这里用子视图还不太准确,我们已经知道通过extends 和 block 来引入母版页,并按模块取代内容。而子视图主要是强调复用,是嵌入到别的视图文件中。jade是用mixin(混合)定义一个部分视图,用‘+’使用 例如:
mixin list
ul
li foo
li bar
li baz +list
+list
输出

比如把页面上显示星星的部分提出来,在view文件夹下建一个_include文件夹,并创建一个rating.jade文件:
mixin outputRating(rating)
- for (var i = 1; i <= rating; i++)
span.glyphicon.glyphicon-star
- for (i = rating; i < 5; i++)
span.glyphicon.glyphicon-star-empty
这样在页面上引用
include _includes/rating
然后在指定位置输出,主要有‘+’号。
p
+outputRating(book.rating)
同理创建了detail.jade 和index.jade
detail.jade
extends layout
include _includes/rating block content
.row
.col-md-9.page.bookdetail
h3=book.title
.row
.col-md-2
img(src='#{book.img}')
.col-md-10
p=book.info
p
+outputRating(book.rating)
p.tags
each tag in book.tags
span=tag
p ISBN:#{book.ISBN}
h3 内容简介
p.brief=book.brief
.col-md-3
.userinfo
p stoneniqiu
index.jade
extends layout block content
.row
.col-md-9.page
.row.topictype
a.label.label-info(href='/') 全部
a(href='/') 读书
a(href='/') 书评
a(href='/') 求书
a(href='/') 求索
each topic in topics
.row.topiclist
img(src='#{topic.img}')
span.count
i.coment=topic.commentCount
i /
i=topic.visitedCount span.label.label-info=topic.type
a(href='/')=topic.title span.pull-right=topic.postTime
a.pull-right.author(href='/')=topic.author .col-md-3
.userinfo
p stoneniqiu

至此,我们创建了三个静态页面,基本熟悉了jade语法。当然jade不止这些,后期随着项目的深入再不断的探索。
部署:
目前我已经将代码提交到github上,然后部署在heroku上。
github:https://github.com/stoneniqiu/ReadingClub 有兴趣的朋友可以一起开发学习。
观摩请戳:https://stoneniqiu-mean.herokuapp.com/

heroku提供了三百兆的免费空间,还有个规则的域名,如何部署请移步:三步将Node应用部署到Heroku上
jade官网:http://jade-lang.com/
jade开源:https://github.com/jadejs/jade
Nodejs之MEAN栈开发(二)----视图与模型的更多相关文章
- Nodejs之MEAN栈开发(三)---- 使用Mongoose创建模型及API
继续开扒我们的MEAN栈开发之路,前面两节我们学习了Express.Jade引擎并创建了几个静态页面,最后通过Heroku部署了应用. Nodejs之MEAN栈开发(一)---- 路由与控制器 Nod ...
- Nodejs之MEAN栈开发(九)---- 用户评论的增加/删除/修改
由于工作中做实时通信的项目,需要用到Nodejs做通讯转接功能,刚开始接触,很多都不懂,于是我和同事就准备去学习nodejs,结合nodejs之MEAN栈实战书籍<Getting.MEAN.wi ...
- Nodejs之MEAN栈开发(五)---- Angular入门与页面改造
这个系列一共会涉及两个JavaScript框架的讲解,一个是Express用做后端,一个是Angular用于前端.和Express一样,Angular分离内容,处理视图.数据和逻辑.和MVC模式很相似 ...
- Nodejs之MEAN栈开发(一)---- 路由与控制器
因为工作需要,最近再次学习了node,上一次学习node是2014年,纯粹是个人兴趣,学了入门之后没有运用,加上赶别的项目又不了了之.这次正好捡起来.废话不多说,这里的MEAN指的是Mongodb.E ...
- Nodejs之MEAN栈开发(八)---- 用户认证与会话管理详解
用户认证与会话管理基本上是每个网站必备的一个功能.在Asp.net下做的比较多,大体的思路都是先根据用户提供的用户名和密码到数据库找到用户信息,然后校验,校验成功之后记住用户的姓名和相关信息,这个信息 ...
- Nodejs之MEAN栈开发(七)---- 用Angular创建单页应用(下)
上一节我们走通了基本的SPA基础结构,这一节会更彻底的将后端的视图.路由.控制器全部移到前端.篇幅比较长,主要分页面改造.使用AngularUI两大部分以及一些优化路由.使用Angular的其他指令的 ...
- Nodejs之MEAN栈开发(六)---- 用Angular创建单页应用(上)
在上一节中我们学会了如何在页面中添加一个组件以及一些基本的Angular知识,而这一节将用Angular来创建一个单页应用(SPA).这意味着,取代我们之前用Express在服务端运行整个网站逻辑的方 ...
- Nodejs之MEAN栈开发(四)---- form验证及图片上传
这一节增加推荐图书的提交和删除功能,来学习node的form提交以及node的图片上传功能.开始之前需要源码同学可以先在git上fork:https://github.com/stoneniqiu/R ...
- Python 全栈开发二 python基础 字符串 字典 集合
一.字符串 1,在python中,字符串是最为常见的数据类型,一般情况下用引号来创建字符串. >>ch = "wallace" >>ch1 = 'walla ...
随机推荐
- HEAP CORRUPTION DETECTED :after Normal block 错误
http://blog.csdn.net/zhccl/article/details/7889590
- UWP学习记录1-开端
UWP学习记录1-开端 1.背景 针对不同基础的人,学习的路线自然是不同的.这篇文章记录的是我个人的学习路线,或者说笔记.我对自己的技术状态的定义是: A.有很好的windows平台编程基础: B.有 ...
- Mac/IOS/linux获取当前时间包含微秒毫秒的代码
#include <sys/time.h> 1 struct UnityLocalTimeStat { int Year; int Month; int DayOfWeek; int Da ...
- linux安装jdk(非rpm命令)
首先查看当前linux上安装的jdk版本: java -version 复制build 后面的jdk信息 卸载: rpm -e java-1.6.0_22-fcs 或者 yum -y remove j ...
- `这个符号在mysql中的作用
` 是 MySQL 的转义符,避免和 mysql 的本身的关键字冲突,只要你不在列名.表名中使用 mysql 的保留字或中文,就不需要转义. 所有的数据库都有类似的设置,不过mysql用的是`而已.通 ...
- 《UML大战需求分析》阅读随笔(三)
一: 需求中提到的各种业务概念.人物等,经过抽象后都可以视之为类. 平时遇到的人.物,我们将遇到的都是具体的人.物,也就如程序中的对象,是一个实实在在的东西. 当我们分析需求的时候,设计模型的时候,我 ...
- OpenCV2.4.13+VS2013开发环境配置
List1:完成 写在前面:之前电脑很杂乱的装了OpenCV的2个版本,在配置OpenCV和VS2013环境时死活配不好.但是接下来的工作要用到,没有办法,还是得好好做.今天重新装了OpenCV2.4 ...
- 朴素贝叶斯算法下的情感分析——C#编程实现
这篇文章做了什么 朴素贝叶斯算法是机器学习中非常重要的分类算法,用途十分广泛,如垃圾邮件处理等.而情感分析(Sentiment Analysis)是自然语言处理(Natural Language Pr ...
- Spark性能优化-coalesce(n)
有时用Spark 运行Job 的时候,输出可能会出现一些空或者小内容.这时重新将输出的Partition 进行重新调整,可以减少RDD中Patition的数目. 两种方式: 1. coalesce(n ...
- [JSOI2008]完美的对称 题解
题目大意: 首先我们给定一点A以及对称中心S,点A'是点A以S为对称中心形成的像点,即点S是线段AA'的对称中心. 点阵组(X)以S为中心的像点是由每个点的像点组成的点阵组.X是用来产生对称中心S的, ...