糖尿病康复,内容丰富有趣,生活中的好帮手!
糖尿病康复 > ASP.NET MVC视图引擎SPARK文档中文版

ASP.NET MVC视图引擎SPARK文档中文版

时间:2018-09-08 06:30:14

相关推荐

ASP.NET MVC视图引擎SPARK文档中文版

一,前言

写个前言还是不错的,可以先让大家看看这个文章是个大体什么内容,然后打酱油的打酱油,路过的继续路过,但相信停下来总有些许收获。

很久没有写东西,一个最近挺忙,二个好像没有什么特别好的内容好写,三个没有什么很好的心得与大家分享。最近一个项目前台使用MVC,用到了SPARK引擎,感觉灰常好用,不敢私藏,拿出来给大家分享一下,而又因为关于SPARK的中文资料简直可以说是没有,所以这篇大家可以认为是翻译,只是翻译水平比较差点,大家凑合了,如果有高手指出不足最好了,抛砖引玉了。

MVC 现在已有四种主要的视图引擎:Spark、NHaml、Razor和传统的ASPX文件模板,Razor是新生事物,传统的ASPX文件模板做过MVC的大体都有了解和应用了,而Spark和NHaml似乎用得不是很多,很有可能是中文资料欠缺,导致连了解的都不多。本人是在搜索关键词 MVC SPARK,百度和GOOGLE都是一篇:《 MVC的四种视图引擎》,文章只是粗略的写了一下各个视图的特点,确实是让大家有了一点点的了解。

本文基本上算是Spark官方文档的翻译,其网址是:/documentation,最近网络河蟹乱爬,如果打不开,请大家自行FQ!

二,将Spark加载到 MVC中

Spark引擎不被controller管理,最简单的方法是在 MVC web应用程序中将SparkViewFactory在Global Application_Start中注册,如:

protected void Application_Start(object sender, EventArgs e)

{

ViewEngines.Engines.Add(new SparkViewFactory());

}

这也是注册其它非默认视图引擎的方法

三,Spark配置

1,web.config中的配置

所有的spark配置都包括在<spark>标签中,如:

<!--增加spark配置名-->

<configSections>

<section name="spark" type="Spark.Configuration.SparkSectionHandler, Spark"/>

</configSections>

<!--spark配置主体-->

<spark>

<compilation debug="true|false" defaultLanguage="Default|CSharp|VisualBasic">

<assemblies>

<add assembly="YourAssemblyName" />

<add assembly="YourOtherStrongAssemblyName, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />

</assemblies>

</compilation>

<pages automaticEncoding="true|false" pageBaseType="Your.NonDefault.BaseSparkView" prefix="{optional string}">

<namespaces>

<add namespace="System"/>

<add namespace="System.Collections.Generic"/>

<add namespace="System.Linq"/>

<add namespace="System.Web.Mvc"/>

</namespaces>

<resources>

<add match="/content/css" location="/youraccount/allstyles/css"/>

<add match="/content/js" location="/youraccount/appname/js"/>

</resources>

</pages>

</spark>

自动解码最好是true,这将会对每个使用${expr}的操作符都进行HTML encoding,而使用方法!{expr}将避免被解码

resources区域用于控制形如”~/“样式的链接,如:<script src="~/content/js/foo.js"/>,将会被解析成给定的location+"/foo.js",对于使用静态文件或CDN来说是非常有意义的。

2,也可以在Application_Start中配置,如:

protected void Application_Start(object sender, EventArgs e)

{

var settings = new SparkSettings()

.SetDebug(true)

.SetPageBaseType("Your.NonDefault.BaseSparkView")

.AddAssembly("YourAssembly")

.AddNamespace("System")

.AddNamespace("System.Collections.Generic")

.AddNamespace("System.Linq")

.AddNamespace("System.Web.Mvc");

ViewEngines.Engines.Add(new SparkViewFactory(settings));

}

四,常规语法

1,包含代码

可以使用包括C#代码,任何helper方法,对象属性或返回非空值的表达式,如:

<p>${"Hello world"}</p>

<p>${Guid.NewGuid().ToString("n")}</p>

代码可以表现为特殊的html标签或其属性,如"if","else"和"var",在这些代码的区域中将不需要使用${},如:

<var names="new [] {'alpha', 'beta', 'gamma'}"/>

<for each="var name in names">

<test if="name == 'beta'">

<p>beta is my favorite.</p>

<else/>

<p>${name} is okay too I suppose.

</test>

</for>

但如果你想输出一个普通标签的属性时,标记符号还是需要加上的,如:

<viewdata currentProduct="Product"/>

<p>${currentProduct.Name} <a href="/Product/Edit/${currentProduct.Id}">Edit</a></p>

2,代码中的特殊字符

可以使用所有的C#代码,但是请小心使用,确保你的商业逻辑都写在你的controller或其它代码中

只有很少一部分的代码需要使用特殊的方法去避免被错误解析,如使用[[和]]代替<>,另外,在属性中如果使用了双引号,那么属性中如果使用了spark语法的字符型值时,则需要使用单引号;如果使用单个char常量,使用(char)'x'代替"x",如:

<viewdata products="IList[[Products]]"/>

<var styles="new[] {'even', 'odd'}"/>

3,配置使用Spark前缀

默认情况下,Spark标签是不需要其它特殊标记的,但是当使用Spark生成xml或xhtml时,配置spark前缀就有必要了,方法如下:

<spark>

<pages prefix="s"/>

</spark>

Or

var settings = new SparkSettings()

.SetPrefix("s");

当配置了前缀时,每个spark标签或属性都需要以前缀开头,以被spark引擎识别,而spark内置的标签如macro:,content:,use:和section:不需要加前缀,如:

<div>

<s:viewdata user="UserInfo"/>

<p s:if="user != null">${user.Name}</p>

<s:LoginForm/>

</div>

4,引入xmlns namespaces至Spark标签中

这个不是太好理解,直接上例子:

<html xmlns="/1999/xhtml"

xmlns:s="/"

xmlns:fn="/macro/">

<body>

<fn:ShowNames favorite="string">

<s:var names="new [] {'alpha', 'beta', 'gamma'}"/>

<s:for each="var name in names">

<s:test if="name == favorite">

<p>${favorite} is my favorite.</p>

<s:else/>

<p>${name} is okay too I suppose.

</s:test>

</s:for>

</fn:ShowNames>

${ShowNames("beta")}

${ShowNames("gamma")}

</body>

</html>

五,变量

1,声明局部变量

使用”var“标签可以简单快速的声明局部变量,默认的行为将会是生成一个有初始值的局部动态变量类型”var“,如:

<var styles="new [] {'odd', 'even'}" i="0"/>

将产生如下:

var styles = new [] {"odd", "even"};

var i = 0;

”var“标签有一个”type“属性,可以指明变量的类型,如:

<var foo="null" bar="null" type="string"/>

将产生如下:

string foo = null;

string bar = null;

最后,如果”var“标签没有在一个以”/>“结尾的标签内声明,变量将会有一个作用域,作用域以”</var>“结束,在作用域外不将不能对变量进行赋值,如:

<div>

<var styles="new [] {'even', 'odd'}" i="0">

<p>${i} is ${styles[i%2]}</p>

</var>

<set i="5"/> <!-- compiler error - variable i is out of scope -->

</div>

将产生如下:

Output.Write("<div>");

{

var styles=new[] {"even", "odd"};

var i = 0;

Output.Write("<p>");

Output.Write(i);

Output.Write(" is ");

Output.Write(styles[i%2]);

Output.Write("</p>");

}

Output.Write("</div>");

i = 5;

2,声明全局变量

局部变量有其作用域,而全局变量可以在view,master或局部模板文件中声明,其值可以在任何地方使用,如:

<h2>${Title}</h2>

<global Title="'My Default Title'"/>

注意到其值是以双引号包围,内部还有单引号(可以理解为双引号是因为HTML标签属性值要以双引号包含,而内部是string类型,用单引号避免外部双引号重复使用)

全局变量实际上将会以视图类中的一个字段成员执行,所以上面例子中将将产生一个object Title="My Default Title"的字段成员,任何方法都可以引用这个变量,spark仍然提供一个”type“属性声明具体类型以避免使用object类型,另外,多个变量可以声明要同一个标签中,如:

<global type="string" Foo="'Hello'" Bar="'World'" />

3,设置局部和全局变量的值

${expr}和其它语法只是用于输出值,局部或全局变量的赋值需要使用”set“标签,如:

<html>

<head>

<global type='string' Title='"Site Name"'/>

<title>${Title}</title>

</head>

<body>

<div><use content="view"/></div>

</body>

</html>

在视图中设置Title的值

<set Title='product.Name + " - " + Title'/>

<!-- or -->

<set Title='string.Format("{0} - {1}", product.Name, Title)'/>

4,使用view data

ViewData作为一个对象字典可以使用形如${ViewData["blah"]}来使用,但是建议使用一个强类型的ViewData将会使操作更为简便,如:

<viewdata

Caption="string"

Products="System.Collections.Generic.IList[[MyApp.Models.Product]]"/>

<div>

<h3>${Caption}</h3>

<div each="var product in Products">

<h4>${product.Name}</h4>

<div>${product.Description}</div>

</div>

</div>

ViewData标签可以声明在view中或是master文件中,结果都是一样的,如:

string Caption

{get {return (string)ViewData["Caption"];}}

System.Collections.Generic.IList<MyApp.Models.Product> Products

{get {return (System.Collections.Generic.IList<MyApp.Models.Product>)ViewData["Products"];}}

在这种情况下,需要使用[[and]]来代替<and>

5,使用view data中的确定类型的model

在view或master文件中viewdata可能有一个model的属性

<viewdata model="MyApp.Models.Catalog"/>

<p>(${ViewData.Model.CatalogID}) ${ViewData.Model.Name} </p>

model的属性可以和其它viewdata中的变量声明共同使用,例如在master文件中使用了一个<viewdata Title="string"/>,在view中仍然可以使用含有一个Title属性的string字段的model,<viewdata model="typename"/>

<viewdata Title="string"/>

<title>${Html.Encode(Title ?? "My Sample MVC Application")}</title>

这一段不好理解,建议大家可以看看英文原文

六,表达式

1,简单的C#表达式

可以使用${expr}或<%=expr%>

例:

<div>

<p>The time is ${DateTime.Now}.</p>

<p>The time is <%=DateTime.Now%>.</p>

</div>

2,Nulls表达式

当使用简单的C#表达式时,如果值为null时,将会输出错误,此时可以使用$!{expr}来避免输出错误,只是输出空值

<div class="shipto">

<p>$!{currentInvoice.ShipTo.FullName}</p>

<p>$!{currentInvoice.ShipTo.Address.City}, $!{currentInvoice.ShipTo.Address.State} $!{currentInvoice.ShipTo.Address.Zip}</p>

</div>

如果是currentInvoice为null或ShipTo为null时,将会输出如下:

<div class="shipto">

<p></p>

<p>, </p>

</div>

这个主意不是太好,不过总比一个乱码错误页好许多,所以确定你的值100%不为空吧

3,使用MVC helpers

可以使用HtmlHelper,UrlHelper和AjaxHelper

<!-- Link to the Sort action on the current controller -->

<p>${Html.ActionLink("Click me", "Sort")}</p>

<!-- Put out data in a way that's safe -->

<p>${Html.Encode(stuff)}</p>

4,条件标签:if,test和else

使用例子说明:

例1:

<var x='5'/>

<if condition='x == 5'>

<p class='resultmessage'>Some value is five</p>

</if>

例2:

<viewdata user='UserInfo'/>

<if condition='!user.IsLoggedIn()'>

<p>Here's a login form</p>

</if>

<else if='user.HasRole(RoleType.Administrator)'>

<p>Hello - you're an admin</p>

</else>

<else if='user.HasRole(RoleType.Registered)'>

<p>Hello - you're a registered user</p>

</else>

<else>

<p>I have no idea what type of person you are</p>

</else>

例3:

可以使用<test if="">语法来代替<if condition="">语法,<else if=""/>和<else/>来代替分散标签

<viewdata user='UserInfo'/>

<test if='!user.IsLoggedIn()'>

<p>Here's a login form</p>

<else if='user.HasRole(RoleType.Administrator)'/>

<p>Hello - you're an admin</p>

<else if='user.HasRole(RoleType.Registered)'/>

<p>Hello - you're a registered user</p>

<else/>

<p>I have no idea what type of person you are</p>

</test>

5,使用if和elseif判断属性或标签显示

if和elseif可以使用在任何标签中

例1:

<var x='5'/>

<p if='x==5' class='resultmessage'>Some value is five</p>

例2:

<use namespace='SampleApp.Models'/>

<viewdata user='UserInfo'/>

<p if='!user.IsLoggedIn()'>Here's a login form</p>

<p elseif='user.HasRole(RoleType.Administrator)'>Hello - you're an admin</p>

<p elseif='user.HasRole(RoleType.Registered)'>Hello - you're a registered user</p>

<else>

<p>I have no idea what type of person you are</p>

</else>

6,一次判断

在页面中只需要调入一次某个资源,如css文件或jquery,可标签中使用once="flagname"还指明,你当然可以使用${expr}或其它语法来为flagname赋值,实际上在spark文件的任何地方都可以使用这样的表达式

<content name="head">

<!-- add jquery if it hasn't been yet, and add countdown plugin -->

<script once="jquery" type="text/javascript" src="~/content/js/jquery-1.2.6.js"/>

<script once="jquery-countdown" type="text/javascript" src="~/content/js/jquery.countdown.js"/>

</content>

这里不是太明白

7,有条件的属性输出

使用?{boolean}表达式只能用在属性值中,例:

<ul>

<li each="var product in Products" class="first?{productIsFirst} last?{productIsLast}">

${H(product.Name)}

</li>

</ul>

将会输出

<ul>

<li class="first">Alpha</li>

<li>Beta</li>

<li>Gamma</li>

<li class=" last">Delta</li>

</ul>

or

<ul>

<li class="first last">just one product</li>

</ul>

如果属性值为空,那么将表现如下:

<input type="checkbox" name="chkhello" checked="?{isHelloChecked}"></input>

将会输出

<input type="checkbox" name="chkhello" checked=""></input>

or

<input type="checkbox" name="chkhello"></input>

8,循环

一个foreach循环包含标签for和each属性,each属性值必须包含类型,变量名,关键字"in"和循环体(collection),如:

<viewdata Posts="IList[[MyApp.Models.Post]"/>

<for each="var post in Posts">

<p>${post.Title}</p>

</for>

任何一个循环都有Index,Count,IsFirst和IsLast属性,在循环作用域内有效,而且只有被使用了才会生成,如:

<viewdata Posts="IList[[MyApp.Models.Post]"/>

<var styles="new[] {'even','odd'}"/>

<for each="var post in Posts">

<p class="${styles[postIndex%2]}">${postIndex}. ${post.Title}</p>

</for>

在循环时,如果使用了Count或IsLast变量,spark将会使用IEnumerable<T>的Linq方法后,使用Count()取得,而旧的spark引擎会先循环一次以取得count,所以使用Count和IsLast时,请注意性能问题

以下是局部变量和循环的复杂使用

<viewdata currentProductId="int"/>

<var styles="new [] {'even', 'odd'}" isCurrent="false">

<for each="var product in Products" isCurrent="product.Id==currentProductId">

<p class="highlighted?{isCurrent} ${styles[productIndex%2]}">${Html.Encode(product.Name)}</p>

</for>

</var>

9,在标签属性中使用循环

例1:

<table>

<tr>

<td>Name</td>

<td>Type</td>

</tr>

<tr each='var user in users'>

<td>${user.Name}</td>

<td>${user.UserType}</td>

</tr>

</table>

例2:

<table>

<tr>

<td>Name</td>

<td>Type</td>

</tr>

<var classes="new [] {'even','odd'}">

<tr each="var user in users" class="${classes[userIndex%2]}">

<td>${userIndex}) ${user.Name}</td>

<td>${user.UserType}</td>

</tr>

</var>

</table>

10,使用命名空间

<use namespace="System.Collections.Generic"/>

<use namespace="System.Web.Mvc"/>

<viewdata Names="IList[[string]]"/>

不好说明

11,内置代码

使用”#“符号声明当前行为C#代码,如:

<test if="user.IsLoggedIn()">

<p>Hello, ${user.Name}.</p>

<else if="user.HasValidTrialSession()"/>

<p>Hello, Valued Future Customer.</p>

<else/>

<p>Hello, er... you.</p>

# System.Diagnostic.Trace.WriteLine("Unexpected anon user.");

# if (System.Diagnostic.Debugger.IsAttached)

# System.Diagnostic.Debugger.Break();

</test>

这里需要说明的是spark变量和C#变量是可以通用的!

12,声明宏

当需要一个helper方法时,如需要输入一些参数和返回一个字符串时,<macro>就可以做这些事情了,声明时使用形如<macro name="foot">,然后使用时用${foo()}或<%=foo()%>,例:

<viewdata errorMessage="string" />

<macro name="ShowError" caption="string" message="string">

<div class="message error">

<h3>${H(caption)}</h3>

<div>${message}</div>

<% Logger.Warn(caption); %> <!-- this is a MR example. mvc would use different logging -->

</div>

</macro>

<h2>Place Order</h2>

<test if="!string.IsNullOrEmpty(errorMessage)">

${ShowError("Failed to place order", errorMessage)}

</test>

将会产生如下:

string ShowError(string caption, string message)

{

using(OutputScope(new System.IO.StringWriter()))

{

Output.Write("\r\n <div class=\"message error\">\r\n <h3>");

Output.Write(H(caption));

Output.Write("</h3>\r\n <div>");

Output.Write(message);

Output.Write("</div>\r\n ");

Logger.Warn(caption);

Output.Write(" </div>\r\n");

return Output.ToString();

}

}

//... and in the RenderViewContent method

Output.Write("\r\n<h2>Place Order</h2>\r\n");

if (!string.IsNullOrEmpty(errorMessage))

{

Output.Write(ShowError("Failed to place order", errorMessage));

} // if (!string.IsNullOrEmpty(errorMessage))

Output.Write("\r\n\r\n<!-- form here, field validation messages, etc. -->\r\n\r\n");

如果觉得《ASP.NET MVC视图引擎SPARK文档中文版》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。