Orchard: Shape展现介绍
????一個shape是一個動態(tài)數(shù)據(jù)模型,shape的目的是用來代替ASP.NET MVC中靜態(tài)的視圖模型,Orchard使用的模型可以在運行時更新。本文將介紹shape的概念以及如何使用它。如果你還不知道m(xù)odule的基本概念和開發(fā)可以看我之前寫的文章,這里就不再重復(fù),如果不知道.Net的動態(tài)對象的可以看看Creating and Using Dynamic Objects。
介紹Shapes
????Shapes是一個動態(tài)數(shù)據(jù)模型,它使用shape templates來展現(xiàn)UI,Shape templates是一個標(biāo)記片段。Shapes的示例包括menus, menu items, content items, documents, and messages。Shape是一個派生自Orchard.DisplayManagement.Shapes.Shape 類的數(shù)據(jù)模型對象。Shape 類不會實例化,而是在運行時通過shape工廠來生成。缺省的shape工廠是Orchard.DisplayManagement.Implementation.DefaultShapeFactory。shape工廠生成的shape是一個動態(tài)對象。
注意: Dynamic objects是.NET 4.0才有的功能。作為一個動態(tài)對象,shape在運行時暴露它的成員,而不是在編譯期。而在ASP.NET MVC中模型對象是一個在編譯器定義的靜態(tài)對象。
??? Shape信息由shape的ShapeMetadata屬性來描述,這些信息包括shape的type、display type、position、prefix、wrappers、alternates、child content和一個WasExecuted 布爾值。我們可以通過以下代碼來獲取shape的元信息:var shapeType = shapeName.Metadata.Type; ??? 當(dāng)shape對象生成之后,我們?nèi)绾握宫F(xiàn)它呢?shape template是一個HEML代碼片段,它負(fù)責(zé)顯示shape。我們還可以不使用shape template而直接通過使用shape attribute (Orchard.DisplayManagement.ShapeAttribute) 來寫代碼顯示shape。
Creating Shapes
????對于模塊開發(fā)人員來說,需要知道我們是在driver中把數(shù)據(jù)轉(zhuǎn)化成模板來顯示的。Driver派生自Orchard.ContentManagement.Drivers.ContentPartDriver,一般都會重載類的Display 和Editor 方法。Display 和Editor 方法返回一個ContentShapeResult對象,這個對象與ASP.NET MVC中的ActionResult類似。
????ContentShape 方法生成一個shape并且把它返回在一個ContentShapeResult 對象中。ContentShape是overloaded的方法,最常用的是傳入兩個參數(shù)(shape 類型和定義shape的動態(tài)函數(shù)表達(dá)式)。動態(tài)函數(shù)表達(dá)式定義這個shape,shape類型命名這個shape并且綁定這個shape到展現(xiàn)模板上。(Shape類型命名規(guī)約在本文后面會介紹)
????以下是一個driver的Display方法示例,這個方法用來顯示一個Map part:
View Code protected override DriverResult Display(MapPart part, string displayType, dynamic shapeHelper)
{
return ContentShape("Parts_Map",
() => shapeHelper.Parts_Map(
Longitude: part.Longitude,
Latitude: part.Latitude));
} ??? 這個表達(dá)式使用一個動態(tài)對象shapeHelper來定義一個Parts_Map shape 和它的屬性。表達(dá)式在shape上添加了一個Longitude 屬性,并且與part的Longitude 屬性綁定起來;同樣增加了一個Latitude 屬性。Display返回ContentShape方法生成的對象。
????下面的示例演示了一個關(guān)于Map part的完整的driver 類,Display 方法用來顯示地圖,Editor 方法標(biāo)記了"GET",用來編輯地圖信息,標(biāo)記了"POST"的Editor方法用來重新顯示用戶提供值的編輯視圖。
View Code using Maps.Models;using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
namespace Maps.Drivers
{
public class MapDriver : ContentPartDriver<MapPart>
{
protected override DriverResult Display(
MapPart part, string displayType, dynamic shapeHelper)
{
return ContentShape("Parts_Map", () => shapeHelper.Parts_Map(
Longitude: part.Longitude,
Latitude: part.Latitude));
}
//GET
protected override DriverResult Editor(
MapPart part, dynamic shapeHelper)
{
return ContentShape("Parts_Map_Edit",
() => shapeHelper.EditorTemplate(
TemplateName: "Parts/Map",
Model: part,
Prefix: Prefix));
}
//POST
protected override DriverResult Editor(
MapPart part, IUpdateModel updater, dynamic shapeHelper)
{
updater.TryUpdateModel(part, Prefix, null, null);
return Editor(part, shapeHelper);
}
}
} 標(biāo)記"GET"的Editor方法使用ContentShape方法來生成一個編輯模板代表的shape對象。在這個例子當(dāng)中,類型名是Parts_Map_Edit,shapeHelper 對象生成一個EditorTemplate shape。這是一個有一個TemplateName 屬性和Model 屬性的shape。TemplateName 屬性表示模板的部分路徑,"Parts/Map" 會告訴Orchard去"Views/EditorTemplates/Parts/Map.cshtml"中查找模板。
這里的Model 屬性代表part的不帶文件擴展名的模型文件名。
Shapes and Templates命名約定
??? 命名約定是很多架構(gòu)現(xiàn)在采用的一種方式,它可以減少一些復(fù)雜性,只要保證遵守一定的約定即可。假使我們要生成一個顯示地圖的Map part,它又精度和緯度兩個屬性。對shape type的命名可能就是Parts_Map。如果shape命名為Parts_Map,那么Orchard 會在views/parts/Map.cshtml中查找模板
下表匯總了shape type和模板的命名約定:
| 應(yīng)用到 | Template命名約定 | Template示例 | Shape Type 示例 |
| Zone | Zone-(zone name) | Zone-AsideSecond.cshtml | Zone__AsideSecond |
| Menu | Menu-(menu name) | Menu-main.cshtml | Menu__main |
| MenuItem | MenuItem-(menu name) | MenuItem-main.cshtml | MenuItem__main |
| Content | Content-(content type) | Content-BlogPost.cshtml | Content__BlogPost |
| Content | Content-(content id) | Content-42.cshtml | Content__42 |
| Content | Content.(display type) | Content.Summary.cshtml | Content_Summary__Page |
| Content | Content-(content type).(display type) | Content-Page.Summary.cshtml | Content_Summary__Page |
| Content.Edit | Content-(content type).Edit | Content-Page.Edit.cshtml | Content_Edit__Page |
| Widget | Widget-(content type) | Widget-HtmlWidget.cshtml | Widget__HtmlWidget |
| Widget | Widget-(zone name) | Widget-AsideSecond.cshtml | Widget__AsideSecond |
| Fields/Common.Text | Fields/Common.Text-(text field name) | Fields/Common.Text-Location.cshtml | Fields_Common_Text__Location |
模板在項目中的位置應(yīng)該遵守以下規(guī)則:
- Content item shape 模板放在views/items 目錄
- Parts_ shape 模板放在views/parts 目錄
- Fields_ shape 模板放在views/fields 目錄下
- EditorTemplate shape 模板放在views/EditorTemplates/template name 目錄。例如,模板名是"Parts/Routable.RoutePart" 的EditorTemplate放在views/EditorTemplates/Parts/Routable.RoutePart.cshtml
- 其他shape模板放在views 目錄下
注意:模板擴展名可以是任意支持的視圖引擎支持的擴展名,例如.cshtml, .vbhtml, .ascx.
模板文件名到shape名的映射
????以下規(guī)則表示從一個模板文件名到對應(yīng)shape名的映射規(guī)則:
- (.) 和 (\) 變成 (_):例如在foo目錄下的bar.cshtml 對應(yīng)的是foo_bar
- (-) 變成兩個下劃線 (__):例如Views/Hello.World.cshtml對應(yīng)的shape名稱為Hello_World,Views/Hello.World-85.cshtml 對應(yīng)的是Hello_World__85
使用模板顯示Shapes
????Shape template是顯示shape的一個代碼片段,在Orchard中缺省的視圖引擎是Razor,在后面文章中我會單獨介紹Razor語法。下面示例把一個Map part顯示為圖片:
View Code <img alt="Location" border="1" src="http://maps.google.com/maps/api/staticmap?&zoom=14
&size=256x256
&maptype=satellite&markers=color:blue|@Model.Latitude,@Model.Longitude
&sensor=false" /> ??? 這個示例顯示一個img 元素,并設(shè)定好帶參數(shù)的src 屬性,在query字符串中, @Model代表傳入到模板中的shape。因此, @Model.Latitude 代表shape的Latitude 屬性, @Model.Longitude 代表shape的Longitude屬性。
下面我們再顯示一個編輯模板,這個模板可以輸入經(jīng)度和緯度值:
<fieldset>
<legend>Map Fields</legend>
<div class="editor-label">
@Html.LabelFor(model => model.Latitude)
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.Latitude)
@Html.ValidationMessageFor(model => model.Latitude)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Longitude)
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.Longitude)
@Html.ValidationMessageFor(model => model.Longitude)
</div>
</fieldset> @Html.LabelFor 表達(dá)式生成一個shape屬性的label, @Html.TextBoxFor 生成輸入shape屬性的文本框, @Html.ValidationMessageFor 生成非法提示信息框。
生成一個shape的方法
????另一種生成并展現(xiàn)shape的方法時生成一個同時定義和展現(xiàn)shape的方法。這個方法必須標(biāo)記Shape 屬性(Orchard.DisplayManagement.ShapeAttribute)。這個方法不適用模板,而是直接返回一個IHtmlString 對象,這個對象包括展現(xiàn)shape的標(biāo)記。
????下面示例是DateTimeRelative shape,這個shape 輸入之前的日期,返回與現(xiàn)在日期的差隔時間:
View Code public class DateTimeShapes : IDependency{
private readonly IClock _clock;
public DateTimeShapes(IClock clock)
{
_clock = clock;
T = NullLocalizer.Instance;
}
public Localizer T { get; set; }
[Shape]
public IHtmlString DateTimeRelative(HtmlHelper Html, DateTime dateTimeUtc)
{
var time = _clock.UtcNow - dateTimeUtc;
if (time.TotalDays > 7)
return Html.DateTime(dateTimeUtc, T("'on' MMM d yyyy 'at' h:mm tt"));
if (time.TotalHours > 24)
return T.Plural("1 day ago", "{0} days ago", time.Days);
if (time.TotalMinutes > 60)
return T.Plural("1 hour ago", "{0} hours ago", time.Hours);
if (time.TotalSeconds > 60)
return T.Plural("1 minute ago", "{0} minutes ago", time.Minutes);
if (time.TotalSeconds > 10)
return T.Plural("1 second ago", "{0} seconds ago", time.Seconds);
return T("a moment ago");
}
}
參考:Accessing and rendering shapes
推薦:你可能需要的在線電子書???
我的新浪圍脖: http://t.sina.com.cn/openexpressapp?? 敏捷個人sina圍裙:http://q.t.sina.com.cn/135484??
歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明:轉(zhuǎn)載自周金根 [ http://zhoujg.cnblogs.com/ ]
轉(zhuǎn)載于:https://www.cnblogs.com/zhoujg/archive/2011/03/03/1969877.html
總結(jié)
以上是生活随笔為你收集整理的Orchard: Shape展现介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 读书笔记 - 企业精简架构
- 下一篇: winform 打包