Yapıcısında veya diğer yöntemlerinde karmaşık bir HTML işaretlemesi oluşturan bir widget, bakımı zor olan çok sayıda spagetti kodu içeren bir sınıfa yol açabilir. Ayrıca işaretleme program kodunda yer aldığından çıktıyı özelleştirmek zor olabilir.
public class MyComplexWidget : Widget
{
public MyComplexWidget(jQueryObject div)
: base(div)
{
var toolbar = J("<div>")
.Attribute("id", this.UniqueName + "_MyToolbar")
.AppendTo(div);
var table = J("<table>")
.AddClass("myTable")
.Attribute("id", this.UniqueName + "_MyTable")
.AppendTo(div);
var header = J("<thead/>").AppendTo(table);
var body = J("<tbody/>").AppendTo(table);
...
...
...
}
}
HTML şablonları kullanılarak bu tür sorunların önüne geçilebilir. Örneğin aşağıdaki şablonu HTML sayfasına ekleyelim:
<script id="Template_MyComplexWidget" type="text/html">
<div id="~_MyToolbar">
</div>
<table id="~_MyTable">
<thead><tr><th>Name</th><th>Surname</th>...</tr></thead>
<tbody>...</tbody>
</table>
</script>
Burada bir SCRIPTetiket kullanılır, ancak türü olarak belirtildiğinde "text/html"tarayıcı onu yürütülecek gerçek bir komut dosyası olarak tanımayacaktır.
TemplatedWidget'ı kullanarak önceki spagetti kod bloğunu yeniden yazalım:
public class MyComplexWidget : TemplatedWidget
{
public MyComplexWidget(jQueryObject div)
: base(div)
{
}
}
Bu widget aşağıdaki gibi bir HTML öğesinde oluşturulduğunda:
<div id="SampleElement">
</div>
Böyle bir HTML işaretlemesiyle karşılaşacaksınız:
<div id="SampleElement">
<div id="MySamples_MyComplexWidget1_MyToolbar">
</div>
<table id="MySamples_MyComplexWidget1_MyTable">
<thead><tr><th>Name</th><th>Surname</th>...</tr></thead>
<tbody>...</tbody>
</table>
</div>
TemplatedWidget sınıfınızın şablonunu otomatik olarak bulur ve bunu HTML öğesine uygular.
TemplatedWidget Kimliği Oluşturma
Dikkatli izlerseniz şablonumuzda alt öğeler için ID'yi ~_MyToolbarve olarak belirttik ~_MyTable.
Ancak bu şablon HTML öğesine uygulandığında ortaya çıkan işaretleme, MySamples_MyComplexWidget1_MyToolbar ve MySamples_MyComplexWidget1_MyTablebunun yerine kimlikleri içeriyordu.
~_TemplatedWidget, widget'ınki UniqueNameve alt çizgi ("_") gibi öneklerin yerini alır ( this.idPrefixbirleşik öneki içerir).
Bu stratejiyi kullanarak, bir sayfada birden fazla HTML öğesi için aynı widget şablonu kullanılsa bile, benzersiz kimliklere sahip olacaklarından kimlikleri birbiriyle çelişmeyecektir.
TemplatedWidget.ByID Yöntem
TemplateWidget bunlara benzersiz bir ad eklediğinden, bir pencere öğesi şablonundaki kimlik nitelikleri, pencere öğesi oluşturulduktan sonra öğelere erişmek için kullanılamaz.
Bir öğeyi bulmak için, widget'ın benzersiz adı ve bir alt çizgi, şablondaki orijinal kimlik özelliğinin başına eklenmelidir:
public class MyComplexWidget : TemplatedWidget
{
public MyComplexWidget(jQueryObject div)
: base(div)
{
J(this.uniqueName + "_" + "Toolbar").AddClass("some-class");
}
}
Bunun yerine TemplatedWidget'ın ByID yöntemi kullanılabilir:
public class MyComplexWidget
{
public MyComplexWidget(jQueryObject div)
: base(div)
{
ByID("Toolbar").AddClass("some-class");
}
}
TemplatedWidget.GetTemplateName Yöntem
Son örnekte MyComplexWidgetşablonunu otomatik olarak buldu.
TemplatedWidget, şablonunu bulmak için bir kuraldan yararlanır (kural tabanlı programlama). Template_Sınıf adından önce önek ekler ve SCRIPTbu kimlik özelliğine ( Template_MyComplexWidget) sahip bir öğeyi arar ve HTML içeriğini şablon olarak kullanır.
Aşağıdaki gibi başka bir kimlik kullanmak istersek:
<script id="TheMyComplexWidgetTemplate" type="text/html">
...
</script>
Tarayıcı konsolunda buna benzer bir hata görülecektir:
Can't locate template for widget 'MyComplexWidget' with name 'Template_MyComplexWidget'!
Şablon kimliğimizi düzeltebilir veya widget'tan özel kimliğimizi kullanmasını isteyebiliriz:
public class MyComplexWidget
{
protected override string GetTemplateName()
{
return "TheMyComplexWidgetTemplate";
}
}
TemplatedWidget.GetTemplate Yöntem
GetTemplateBaşka bir kaynaktan şablon sağlamak veya manuel olarak belirtmek için yöntem geçersiz kılınabilir:
public class MyCompleWidget
{
protected override string GetTemplate()
{
return $('#TheMyComplexWidgetTemplate').GetHtml();
}
}
Q.GetTemplate Yöntemi ve Sunucu Tarafı Şablonları
TemplatedWidget.GetTemplateYöntem çağrıları için varsayılan uygulama ve bu kimliğe sahip GetTemplateNamebir öğeyi arar .SCRIPT
Eğer böyle bir SCRIPT elemanı bulunamazsa Q.GetTemplateaynı ID ile çağrılır.
Her ikisi de sonuç döndürmezse bir hata atılır.
Q.GetTemplateyöntemi sunucu tarafında tanımlanan şablonlara erişim sağlar. .template.cshtmlBu şablonlar, uzantıları olan dosyalardan ~/Views/Templateveya ~/Modulesklasörlerden veya bunların alt klasörlerinden derlenir .
~/Views/Template/SomeFolder/MyComplexWidget.template.cshtmlÖrneğin, aşağıdaki içerikte olduğu gibi sunucu tarafındaki bir dosyada MyComplexWidget için bir şablon oluşturabiliriz :
<div id="~_MyToolbar">
</div>
<table id="~_MyTable">
<thead><tr><th>Name</th><th>Surname</th>...</tr></thead>
<tbody>...</tbody>
</table>
Şablon dosya adı ve uzantısı önemlidir, ancak klasörü göz ardı edilir.
Bu stratejiyi kullanarak sayfa işaretlemesine widget şablonları eklemeye gerek kalmayacaktır.
Ayrıca, bu tür sunucu tarafı şablonları ilk kullanımda yüklendiğinden ( tembel yükleme ) ve tarayıcıda ve sunucuda önbelleğe alındığından, sayfa işaretlemesi, belirli bir sayfada asla kullanamayacağımız widget şablonlarıyla kirlenmez. Bu nedenle, sunucu tarafı şablonları satır içi SCRIPT şablonlarına göre tercih edilir.