Nancy简单实战之NancyMusicStore(二):打造首页
前言
继上一篇搭建好项目之后,我们在这一篇中将把我们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来解析的,并且后面用到的RenderBody和RenderSection都是要加上这句代码之后才能用的。
其次,RenderBody和RenderSection这两个东东,大家应该是很熟悉的了。
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之大杂烩
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
如何用 Python 和 API 收集与分析网络数据?
本文以一款阿里云市场历史天气查询产品为例,为你逐步介绍如何用 Python 调用 API 收集、分析与可视化数据。希望你举一反三,轻松应对今后的 API 数据收集与分析任务。 雷同 上周的研究生课,学生分组展示实践环节第二次作业,主题是利用 API 获取、分析与可视化数据。 大家做的内容,确实五花八门。 例如这个组,调查对象是动画片《小猪佩奇》(英文名 “Peppa Pig”,又译作《粉红猪小妹》)。这部片子据说最近很火。 猜猜看,下面这一组调查对象是什么? 没错,是《权力的游戏》(Game of Thrones)。一部很好看的美剧。 主题丰富多彩,做得有声有色。 作为老师,我在下面,应该很开心吧? 不,我简直哭笑不得。 14个组中,有一多半都和他们一样,做的是维基百科页面访问量分析。 为什么会这样呢? 因为我在布置作业的时候,很贴心地给了一个样例,是我之前写的一篇教程《如何用R和API免费获取Web数据?》。 于是,他们就都用 R 语言,来分析维基百科页面访问量了。 这些同学是不是太懒惰了? 听了他们的讲述,我发觉,其中不少同学,是非常想做些新东西的。 他们找了国内若干个云市场,去找...
- 下一篇
当我们聊技术实力的时候,我们到底在聊什么
技术实力的迷思 俗话说“文无第一,武无第二”,技术就是一种“文”的能力,很多时候我们很难直观看出一个技术人员的实力,但不管是公司招聘的面试,还是公司内部的晋升面评,都需要在较短时间内快速判断一个技术人员的实力。正因为技术实力评价本身没有绝对客观的标准,很多时候都会听到类似的吐槽: “我们组内的 XX 技术实力不如我,竟然他晋升通过了,我却被刷掉了,评委真的是~!@#¥”…… “面试官问的都是什么鬼问题,我知道的基本没问,我感觉他根本不会考察我的技术实力”…… “听说算法和数据结构最能体现程序员的实力,我要好好啃啃《算法导论》”(然而啃完又忘记了)…… …… 还有很多类似的问题和吐槽,背后都可以归纳为一个问题:当我们聊技术实力的时候,我们到底在聊什么? 有的人认为:技术实力就是指算法和数据结构很厉害…… 有的人认为:研究过 Linux 内核源码和看懂《深入浅出 MFC》的才是技术牛逼的人…… 有的人认为:会写 C++ 的才是真正的技术高手,因为 C++ 的对象初始化有 N 种写法…… 有的人认为:技术高手必须对业务很熟悉…… 有的人认为:贡献了开源项目代码的才是技术牛人…… 有的人认为:...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Red5直播服务器,属于Java语言的直播服务器
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- Windows10,CentOS7,CentOS8安装Nodejs环境
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS7,8上快速安装Gitea,搭建Git服务器