Nodejs之MEAN栈开发(二)----视图与模型

2016-06-02 08:30 by stoneniqiu, 92 阅读, 2 评论, 收藏编辑

上一节做了对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

 

运行起来,看到导航条

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

出现这样的页面是因为在上文中,在app.js中有过设置
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:

 
 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)
这里的mixin就相当于是一个JavaScript函数,可以传递多个参数。 更多内容可以移步 http://jade-lang.com/ jade官网。

同理创建了detail.jade 和index.jade

detail.jade

 

index.jade

 

至此,我们创建了三个静态页面,基本熟悉了jade语法。当然jade不止这些,后期随着项目的深入再不断的探索。

部署:

目前我已经将代码提交到github上,然后部署在heroku上。

github:https://github.com/stoneniqiu/ReadingClub 有兴趣的朋友可以一起开发学习。

观摩请戳:https://stoneniqiu-mean.herokuapp.com/

heroku提供了三百兆的免费空间,还有个规则的域名,如何部署请移步:三步将Node应用部署到Heroku上

小结:这一节主要是学习了jade引擎,目前的数据模型就是json对象。对比Asp.net MVC的Razor引擎,元素输出和子视图区各有千秋。jade的代码量更少,用缩进处理嵌套,子视图就相当于是@Html.Partial()。 目前网站都还是静态的,下一节将介绍mongodb和mongoose,实现对数据的操作,让页面动态化。

jade官网:http://jade-lang.com/

jade开源:https://github.com/jadejs/jade

理想就是自己喜欢做,并对社会和他人都有意义的事情!

出处:http://www.cnblogs.com/stoneniqiu/

MEAN栈开发的更多相关文章

  1. .NET全栈开发工程师学习路径

    PS:最近一直反复地看博客园以前发布的一条.NET全栈开发工程师的招聘启事,觉得这是我看过最有创意也最朴实的一个招聘启事,更为重要的是它更像是一个技术提纲,能够指引我们的学习和提升,现在转载过来与各位 ...

  2. Python全栈开发【面向对象进阶】

    Python全栈开发[面向对象进阶] 本节内容: isinstance(obj,cls)和issubclass(sub,super) 反射 __setattr__,__delattr__,__geta ...

  3. Python全栈开发【面向对象】

    Python全栈开发[面向对象] 本节内容: 三大编程范式 面向对象设计与面向对象编程 类和对象 静态属性.类方法.静态方法 类组合 继承 多态 封装 三大编程范式 三大编程范式: 1.面向过程编程 ...

  4. Python全栈开发【模块】

    Python全栈开发[模块] 本节内容: 模块介绍 time random os sys json & picle shelve XML hashlib ConfigParser loggin ...

  5. Python全栈开发【基础四】

    Python全栈开发[基础四] 本节内容: 匿名函数(lambda) 函数式编程(map,filter,reduce) 文件处理 迭代器 三元表达式 列表解析与生成器表达式 生成器 匿名函数 lamb ...

  6. Python全栈开发【基础三】

    Python全栈开发[基础三]  本节内容: 函数(全局与局部变量) 递归 内置函数 函数 一.定义和使用 函数最重要的是减少代码的重用性和增强代码可读性 def 函数名(参数): ... 函数体 . ...

  7. Nodejs之MEAN栈开发(三)---- 使用Mongoose创建模型及API

    继续开扒我们的MEAN栈开发之路,前面两节我们学习了Express.Jade引擎并创建了几个静态页面,最后通过Heroku部署了应用. Nodejs之MEAN栈开发(一)---- 路由与控制器 Nod ...

  8. Nodejs之MEAN栈开发(二)----视图与模型

    上一节做了对Express做了简单的介绍,提出了controller,介绍了路由.这一节将重点放到视图和模型上,完成几个静态页面并部署到heroku上. 导航 前端布局使用bootstrap,从官网下 ...

  9. 用“MEAN”技术栈开发web应用(三)用mongodb搭建数据库

    上一篇介绍了如何用express搭建起服务端MVC的开发架构,本篇我们来详细介绍一下这个Model层,也就是数据库访问层.包含如何使用mongodb搭建数据库,以及如何使用mongoose来访问数据. ...

  10. Python全栈开发【基础二】

    Python全栈开发[基础二] 本节内容: Python 运算符(算术运算.比较运算.赋值运算.逻辑运算.成员运算) 基本数据类型(数字.布尔值.字符串.列表.元组.字典) 其他(编码,range,f ...

随机推荐

  1. C语言中没有main函数生成可执行程序的几种方法

    1.define预处理指令 这种方式很简单,只是简单地将main字符串用宏来代替,或者使用##拼接字符串.示例程序如下: #include <stdio.h> #define begin ...

  2. stm32之595(spi芯片)

    595是一款串转并的芯片:  (三极管的功能) /*Include---------------------------*/ #include"stm32f10x_lib.h" / ...

  3. C# 中根据datetime的值来计算属于本年的第几周,类似delphi中的weekoftheyear功能

    /// <summary> /// 获得今天是今年的第几周 /// </summary> /// <param name="year">< ...

  4. G - I Think I Need a Houseboat(简单题,粘贴下来是因为数据精度需要注意)

    These will be floating point numbers:看这句话,就是说数据会是浮点型的, 问题(一)数据定义成double类型就过了 我当时以为定义成float类型就可以了, 因为 ...

  5. 应用之间进行跳转,ComponentName的方式

    从应用A跳转到应用B, 关键代码如下: 有以下几个注意点: 1.ComponentName cn = new ComponentName("com.terry", "co ...

  6. C#路径,文件,目录,I/O常见操作

         C#路径,文件,目录,I/O常见操作 文件操作是程序中非常基础和重要的内容,而路径.文件.目录以及I/O都是在进行文件操作时的常见主题,这里想把这些常见的问题作个总结,对于每个问题,尽量提供 ...

  7. 将时间显示为“刚刚”“n分钟/小时前”等

    在很多场合为了显示出信息的及时性,一般会将时间显示成“刚刚”,“5分钟前”,“3小时前”等,而不是直接将时间打印出来.比如微博,SNS类应用就最长用到这个功能.而一般存储在数据库中的时间格式为 Uni ...

  8. HDU 3909 DLX

    http://blog.csdn.net/sr_19930829/article/details/39756513 http://www.kuangbin.net/archives/hdu4069-d ...

  9. Ant学习实例

    ant   目录(?)[+] Ant学习实例 安装Ant 基础元素 project元素 target元素 property元素 完整示例   Ant学习实例 1.安装Ant 先从http://ant. ...

  10. hadoop安全模式

      hadoop安全模式在分布式文件系统启动的时候,开始的时候会有安全模式,当分布式文件系统处于安全模式的情况下,文件系统中的内容不允许修改也不允许删除,直到安全模式结束.安全模式主要是为了系统启动的 ...