Nancy简单实战之NancyMusicStore(二):打造首页
前言
繼上一篇搭建好項(xiàng)目之后,我們?cè)谶@一篇中將把我們NancyMusicStore的首頁(yè)打造出來(lái)。
布局
開(kāi)始首頁(yè)之前,我們要先為我們的整個(gè)應(yīng)用添加一個(gè)通用的布局頁(yè)面,WebForm中母版頁(yè)的概念。
添加一個(gè)Views/Shared文件夾,同MVC應(yīng)用程序一樣,我們將布局 _Layout.cshtml 放到這個(gè)文件夾下面,具體內(nèi)容如下:
@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>下面解釋一下這個(gè)布局頁(yè),
首先是頁(yè)面最上面的這句代碼: @inherits Nancy.ViewEngines.Razor.NancyRazorViewBase<dynamic>
這句代碼看上去很像我們?cè)谝话鉓VC視圖中寫(xiě)的 @model namespace.modelname ,但是我們卻沒(méi)有在布局頁(yè)面寫(xiě)過(guò)這個(gè)吧!
其實(shí)我們可以從字面意義來(lái)理解,inherits是繼承的意思,后面的是Nancy自己實(shí)現(xiàn)的Razor引擎的某個(gè)類(lèi)
所以表明這個(gè)頁(yè)面是用Razor來(lái)解析的,并且后面用到的RenderBody和RenderSection都是要加上這句代碼之后才能用的。
其次,RenderBody和RenderSection這兩個(gè)東東,大家應(yīng)該是很熟悉的了。
RenderBody說(shuō)明的是這里預(yù)留了一個(gè)點(diǎn)位符,用到這個(gè)布局的視圖就是在這里呈現(xiàn)的
RenderSection指明了在頁(yè)面中存在一個(gè)塊(一般用于寫(xiě)JS),名字是scripts,required:false說(shuō)明這一個(gè)塊不是必須的,當(dāng)在視圖中用到了這個(gè)塊的時(shí)候,在頁(yè)面寫(xiě)的內(nèi)容就在這里呈現(xiàn)
最后還要說(shuō)明的是:導(dǎo)航菜單里面購(gòu)物車(chē)的數(shù)量和商品分類(lèi)列表在MVCMusicStore中是用Html.RenderAction來(lái)實(shí)現(xiàn)的,但是在Nancy中,
并沒(méi)有這個(gè)HtmlHelper,我們?cè)谶@里也不去擴(kuò)展這個(gè)Helper,所以這兩個(gè)地方后面會(huì)用ajax來(lái)簡(jiǎn)單處理一下。
到這里,我們的布局是已經(jīng)寫(xiě)好了。
不知道大家是否還記得 _ViewStart.cshtml 這個(gè)文件?這個(gè)文件指定了我們Razor引擎的默認(rèn)視圖母版頁(yè)面。在MVC中它的內(nèi)容一般是
@{Layout = "~/Views/Shared/_Layout.cshtml"; }在Nancy中,還是有一點(diǎn)點(diǎn)區(qū)別的,在Views文件夾下面,我們新建了一個(gè)_ViewStart.cshtml文件,其內(nèi)容如下:
@{Layout = "Views/Shared/_Layout.cshtml"; }各位應(yīng)該也看到兩者之間的區(qū)別了,Nancy中沒(méi)有帶 ~/ 字符!這個(gè)是兩者之間路徑處理的問(wèn)題,這個(gè)是很值得注意的地方!
到_ViewStart.cshtml這一步,才真正的算是完成了我們的布局。
Module
接下來(lái)就是Module層的實(shí)現(xiàn)了,這一層可以看作是,MVC中的控制器。
添加一個(gè)Modules文件夾,用來(lái)存放我們的modules。
先在Modules文件夾添加一個(gè)HomeModule.cs,用于展示我們的首頁(yè)。
其內(nèi)容如下:
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;}} }這里要明確幾點(diǎn):
我們寫(xiě)的module都要繼承nancy的nancymodule
所有的路由入口都是在構(gòu)造函數(shù)中指定的
可以看到我們的HomeModule只能接收一個(gè)GET請(qǐng)求,這個(gè)GET請(qǐng)求就是我們的首頁(yè)地址,它返回了一個(gè)視圖
這個(gè)視圖還帶了一個(gè)強(qiáng)類(lèi)型的最高銷(xiāo)售專(zhuān)輯列表,這點(diǎn)與MVC可以說(shuō)是無(wú)縫對(duì)接的。
這個(gè)最高銷(xiāo)售列表是用PG的存儲(chǔ)過(guò)程來(lái)取的數(shù)據(jù),內(nèi)容如下:
-- 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.0VOLATILE 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 ALEFT JOIN orderdetails O ON A.albumid = O.albumidGROUP BY A.albumid,A.genreid,A.artistid,A.title,A.price,A.albumarturlORDER BY count(O.albumid) desc LIMIT num; end;$function$;ALTER FUNCTION public.get_top_selling_albums(integer)OWNER TO dev;需要說(shuō)明的是,pg里面過(guò)程是用funtionn來(lái)體現(xiàn)的。
后臺(tái)處理邏輯有了,下面就是視圖這一塊了,說(shuō)到視圖,Nancy的形式也和ASP.NET MVC的類(lèi)似。
我們?cè)赩iews文件夾建一個(gè)Home文件夾,再在Home文件夾下面新建一個(gè)Index.cshtml。(不是一定要按這樣來(lái)做!!)
下面來(lái)看看Index.cshtml的具體內(nèi)容:
@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>是一些比較常規(guī)的頁(yè)面操作,只要是符合Razor的語(yǔ)法即可。
此時(shí)效果如下:
前面還提到分類(lèi)列表和購(gòu)物車(chē)數(shù)量的問(wèn)題。我們?cè)谶@里先處理分類(lèi)列表的問(wèn)題。
回到_Layout.cshtml中,在頁(yè)面底部添加一段js,讓它在加載的時(shí)候就通過(guò)異步請(qǐng)求把分類(lèi)加載出來(lái),具體如下:
<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>這個(gè)url是和MVC MusicStore保持一致的!
所以我們?cè)贛odules文件夾下面再建了一個(gè)StoreModule用于接收這個(gè)ajax請(qǐng)求,具體如下:
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的構(gòu)造函數(shù)有一個(gè)base("/store"),這一個(gè)就是表明這個(gè)Module的路由起點(diǎn)是 http://yourdomain.com/store
我們發(fā)起的GET請(qǐng)求的URL是/store/genremenu,所以要在構(gòu)造函數(shù)中添加一個(gè)GET請(qǐng)求來(lái)返回結(jié)果。
至此,我們的首頁(yè)已經(jīng)可以拿的出手給人看了:
下一篇將是完善商品瀏覽相關(guān)的內(nèi)容,以及商品的管理。
本文也已經(jīng)同步到 Nancy之大雜燴
總結(jié)
以上是生活随笔為你收集整理的Nancy简单实战之NancyMusicStore(二):打造首页的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Redis简单案例(二) 网站最近的访问
- 下一篇: JavaScript变量和对象参数传值问