前言

继上一篇搭建好项目之后,我们在这一篇中将把我们NancyMusicStore的首页打造出来。

布局

开始首页之前,我们要先为我们的整个应用添加一个通用的布局页面,WebForm中母版页的概念。

添加一个Views/Shared文件夹,同MVC应用程序一样,我们将布局 _Layout.cshtml 放到这个文件夹下面,具体内容如下:

@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase<dynamic>
<!DOCTYPE html>
<html>
<head>
<title>@ViewBag.Title</title>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link href="~/Content/Site.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="header">
<h1><a href="/">NancyFx MUSIC STORE</a></h1>
<ul id="navlist">
<li class="first"><a href="/" id="current">Home</a></li>
<li><a href="/store">Store</a></li>
<li><a id="cart-status" href="/shoppingcart/index"></a></li>
<li><a href="/storemanager">Admin</a></li>
</ul>
</div> <ul id="categories">
</ul> <div id="main">
@RenderBody()
</div> <div id="footer">
built with <a href="http://nancyfx.org">Nancy 1.4.3</a>
</div> <script src="~/Scripts/jquery-1.5.1.min.js" type="text/javascript"></script>
@RenderSection("scripts", required: false)
</body>
</html>

下面解释一下这个布局页,

首先是页面最上面的这句代码: @inherits Nancy.ViewEngines.Razor.NancyRazorViewBase<dynamic>

这句代码看上去很像我们在一般MVC视图中写的 @model namespace.modelname ,但是我们却没有在布局页面写过这个吧!

其实我们可以从字面意义来理解,inherits是继承的意思,后面的是Nancy自己实现的Razor引擎的某个类

所以表明这个页面是用Razor来解析的,并且后面用到的RenderBodyRenderSection都是要加上这句代码之后才能用的。

其次,RenderBodyRenderSection这两个东东,大家应该是很熟悉的了。

  • RenderBody说明的是这里预留了一个点位符,用到这个布局的视图就是在这里呈现的

  • RenderSection指明了在页面中存在一个块(一般用于写JS),名字是scripts,required:false说明这一个块不是必须的,当在视图中用到了这个块的时候,在页面写的内容就在这里呈现

最后还要说明的是:导航菜单里面购物车的数量和商品分类列表在MVCMusicStore中是用Html.RenderAction来实现的,但是在Nancy中,

并没有这个HtmlHelper,我们在这里也不去扩展这个Helper,所以这两个地方后面会用ajax来简单处理一下。

到这里,我们的布局是已经写好了。

不知道大家是否还记得 _ViewStart.cshtml 这个文件?这个文件指定了我们Razor引擎的默认视图母版页面。在MVC中它的内容一般是

@{
Layout = "~/Views/Shared/_Layout.cshtml";
}

在Nancy中,还是有一点点区别的,在Views文件夹下面,我们新建了一个_ViewStart.cshtml文件,其内容如下:

@{
Layout = "Views/Shared/_Layout.cshtml";
}

各位应该也看到两者之间的区别了,Nancy中没有带 ~/ 字符!这个是两者之间路径处理的问题,这个是很值得注意的地方!

到_ViewStart.cshtml这一步,才真正的算是完成了我们的布局。

Module

接下来就是Module层的实现了,这一层可以看作是,MVC中的控制器。

添加一个Modules文件夹,用来存放我们的modules。

先在Modules文件夹添加一个HomeModule.cs,用于展示我们的首页。

其内容如下:

using Nancy;
using NancyMusicStore.Common;
using NancyMusicStore.Models;
using System.Collections.Generic;
using System.Data;
using System.Linq; namespace NancyMusicStore.Modules
{
public class HomeModule : NancyModule
{
public HomeModule() : base("/")
{
Get["/"] = _ =>
{
var albums = GetTopSellingAlbums(5);
return View["Index", albums];
};
} /// <summary>
/// get top count selling albums
/// </summary>
/// <param name="count"></param>
/// <returns></returns>
private List<Album> GetTopSellingAlbums(int count)
{
string sql = "public.get_top_selling_albums";
var list = DBHelper.Query<Album>(sql, new
{
num = count
}, null, true, null, CommandType.StoredProcedure).ToList();
return list;
}
}
}

这里要明确几点:

  • 我们写的module都要继承nancy的nancymodule

  • 所有的路由入口都是在构造函数中指定的

可以看到我们的HomeModule只能接收一个GET请求,这个GET请求就是我们的首页地址,它返回了一个视图

这个视图还带了一个强类型的最高销售专辑列表,这点与MVC可以说是无缝对接的。

这个最高销售列表是用PG的存储过程来取的数据,内容如下:

-- FUNCTION: public.get_top_selling_albums(integer)

-- DROP FUNCTION public.get_top_selling_albums(integer);

CREATE OR REPLACE FUNCTION public.get_top_selling_albums(
num integer)
RETURNS SETOF "TABLE(albumid integer, genreid integer, artistid integer, title character varying, price numeric, albumarturl character varying)"
LANGUAGE 'plpgsql'
COST 100.0
VOLATILE NOT LEAKPROOF
ROWS 1000.0
AS $function$ begin
RETURN QUERY SELECT
A.albumid,
A.genreid,
A.artistid,
A.title,
A.price,
A.albumarturl
FROM albums A
LEFT JOIN orderdetails O ON A.albumid = O.albumid
GROUP BY A.albumid,A.genreid,A.artistid,A.title,A.price,A.albumarturl
ORDER BY count(O.albumid) desc LIMIT num;
end; $function$; ALTER FUNCTION public.get_top_selling_albums(integer)
OWNER TO dev;

需要说明的是,pg里面过程是用funtionn来体现的。

后台处理逻辑有了,下面就是视图这一块了,说到视图,Nancy的形式也和ASP.NET MVC的类似。

我们在Views文件夹建一个Home文件夹,再在Home文件夹下面新建一个Index.cshtml。(不是一定要按这样来做!!)

下面来看看Index.cshtml的具体内容:

@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase<List<NancyMusicStore.Models.Album>>
@{
ViewBag.Title = "NancyFx Music Store";
}
<div id="promotion">
</div> <h3><em>Fresh</em> off the grill</h3> <ul id="album-list">
@foreach (var album in Model)
{
<li>
<a href="javascript:;">
<img alt="@album.Title" src="@album.AlbumArtUrl" />
<span>@album.Title</span>
</a>
</li>
}
</ul>

是一些比较常规的页面操作,只要是符合Razor的语法即可。

此时效果如下:

前面还提到分类列表和购物车数量的问题。我们在这里先处理分类列表的问题。

回到_Layout.cshtml中,在页面底部添加一段js,让它在加载的时候就通过异步请求把分类加载出来,具体如下:

<script type="text/javascript">
$(function () {
$.ajax({
url: "/store/genremenu",
method: "get",
dataType: "json",
success: function (res) {
for (var i = 0; i < res.length; i++) {
$("#categories").append('<li><a href="javascript:;">' + res[i].name + '</a></li>');
}
}
});
});
</script>

这个url是和MVC MusicStore保持一致的!

所以我们在Modules文件夹下面再建了一个StoreModule用于接收这个ajax请求,具体如下:

using Nancy;
using NancyMusicStore.Common;
using NancyMusicStore.Models;
using NancyMusicStore.ViewModels;
using System.Collections.Generic;
using System.Data;
using System.Linq; namespace NancyMusicStore.Modules
{
public class StoreModule : NancyModule
{
public StoreModule() : base("/store")
{
Get["/genremenu"] = _ =>
{
return Response.AsJson(GetGenreList());
};
} private IList<Genre> GetGenreList()
{
string cmd = "public.get_all_genres";
return DBHelper.Query<Genre>(cmd, null, null, true, null, CommandType.StoredProcedure);
}
}
}

在StoreModule的构造函数有一个base("/store"),这一个就是表明这个Module的路由起点是 http://yourdomain.com/store

我们发起的GET请求的URL是/store/genremenu,所以要在构造函数中添加一个GET请求来返回结果。

至此,我们的首页已经可以拿的出手给人看了:

下一篇将是完善商品浏览相关的内容,以及商品的管理。

本文也已经同步到 Nancy之大杂烩

Nancy简单实战之NancyMusicStore(二):打造首页的更多相关文章

  1. Nancy简单实战之NancyMusicStore(六):写在最后

    前言 由于公司搬家后,住的地方离上班的地方远了N倍,以前是走路十多分钟就可以到公司的,上班时间也从9:00提早到8:30 现在每天上班都是先坐公交,然后再坐地铁,在这段路上比较浪费时间而且每天都是要6 ...

  2. Nancy简单实战之NancyMusicStore(三):完善商品信息与管理

    前言 上一篇,我们做了不少准备,并且还把我们NancyFx音乐商城的首页打造好了.这一篇主要是完善我们在首页的商品浏览问题和添加对商品的管理. 下面开始正题: 商品详情 首先是查看单个商品的详情: 先 ...

  3. Nancy简单实战之NancyMusicStore(四):实现购物车

    前言 上一篇,我们完成了商品的详情和商品的管理,这一篇我们来完成最后的一个购物车功能. 购物车,不外乎这几个功能:添加商品到购物车,删除购物车中的商品,对购物车中的商品进行结算. MVC MusicS ...

  4. Nancy简单实战之NancyMusicStore(一):准备工作和搭建项目

    开发环境 OS : Windows 10 10.0.14393 IDE : Visual Studio 2015 Community With Update 3 Database : PostgreS ...

  5. Nancy简单实战之NancyMusicStore(五):部署上线

    前言 经过本系列前面四篇文章,NancyMusicStore已经开发完成了,下面就差部署上线了,我们会在两个不同的环境部署.其实之前的文章也有讲解在 Linux下部署的相关事宜.下面开始本文的内容. ...

  6. Fiddler实战深入研究(二)

    Fiddler实战深入研究(二) 阅读目录 Fiddler不能捕获chrome的session的设置 理解数据包统计 请求重定向(AutoResponder) Composer选项卡 Filters选 ...

  7. 工作经常使用的SQL整理,实战篇(二)

    原文:工作经常使用的SQL整理,实战篇(二) 工作经常使用的SQL整理,实战篇,地址一览: 工作经常使用的SQL整理,实战篇(一) 工作经常使用的SQL整理,实战篇(二) 工作经常使用的SQL整理,实 ...

  8. AspNetCore-MVC实战系列(二)之通过绑定邮箱找回密码

    AspNetCore - MVC实战系列目录 . 爱留图网站诞生 . AspNetCore - MVC实战系列(一)之Sqlserver表映射实体模型 . AspNetCore-MVC实战系列(二)之 ...

  9. Python3从零开始爬取今日头条的新闻【二、首页热点新闻抓取】

    Python3从零开始爬取今日头条的新闻[一.开发环境搭建] Python3从零开始爬取今日头条的新闻[二.首页热点新闻抓取] Python3从零开始爬取今日头条的新闻[三.滚动到底自动加载] Pyt ...

随机推荐

  1. Android——init可执行程序

    init进程是Android启动后,系统执行的第一个名称为init的可执行程序. 功能: 设备管理 解析启动脚本init.rc 执行启动脚本中的基本功能 执行启动脚本中的各种服务 代码路径:syste ...

  2. CentOS 6.4 x64 Cacti 监控安装配置

    Cacti 监控安装配置   环境:   安装Cacti 的服务器   Linux 6.4 x64   ip 10.8.8.11     一: 配置iptables , selinux     vi ...

  3. md5sum校验文件完整性

    1.简介 MD5算法常常被用来验证网络文件传输的完整性,防止文件被人篡改. MD5 全称是报文摘要算法(Message-Digest Algorithm 5),此算法对任意长度的信息逐位进行计算,产生 ...

  4. 控制流之if

    if语句if语句用来检验一个条件, 如果 条件为真,我们运行一块语句(称为 if-块 ), 否则 我们处理另外一块语句(称为 else-块 ). else 从句是可选的. ~~~~~~~~~~~~~~ ...

  5. KEIL MDK 查看代码量、RAM使用情况--RO-data、RW-data、ZI-data的解释(转)

    源:KEIL MDK 查看代码量.RAM使用情况--RO-data.RW-data.ZI-data的解释 KEIL RVMDK编译后的信息 Program Size: Code=86496 RO-da ...

  6. HUST 1351 Group

    (莫名其妙的被一个叫布布扣的网站收录了......什么鬼) 简单DP.dp[i][j]表示把前i个数字分成j段的最优解, 递推式很容易写: (其中sum[]是前缀和:p <= i - L,并且前 ...

  7. AFNetWorking发送post请求,Code=-1016错误

    使用AFNetWorking发送post请求时,可能会出现下面Code=-1016问题.打印的error如下: Error:Error Domain=com.alamofire.error.seria ...

  8. ucos内存管理原理详解

    应用程序中为了某种特殊需要,经常需要动态的分配内存,而操作系统的特质置一,就是能不能保证动态内存分配的时效性,也就是说分配时间是可确定的 Ucos提供内存分配功能,它将内存空间分为两级管理,将一块连续 ...

  9. ubuntu10.4的更新源因过期无法更新的解决方法

    转载自:http://blog.csdn.net/suquan629/article/details/52333769 ubuntu10.4到2016年早已停止了更新支持,ubuntu也不再维护了.官 ...

  10. 【转】10款GitHub上最火爆的国产开源项目

    将开源做到极致,提高效率方便更多用户 接触开源时间虽然比较短但是后续会努力为开源社区贡献自己微薄的力量 衡量一个开源产品好不好,看看产品在 GitHub 的 Star 数量就知道了.由此可见,GitH ...