صفحات ZML
قررت
أن أجرب Vazor عمليا في تحويل صفحات موقع ويب مكتوبة بـ chtml إلى vbxml.
ورغم
أني نجحت في تحويل الصفحات وحتى مكونات الصفحات Razor Components فقد
اكتشفت عيبا كبيرا في كود vbxml وهو عدم توافقه مع مساعدات التيجان Tag Helpers في
قليل ن الحالات، لكنها للأسف الحالات الأهم والأكثر فائدة!
وقد
وجدت حلولا لهذه المشكلة، لكنها تتطلب تعريف خاصية إضافية في ملف كود فيجوال
بيزيك، وكتابة كود طويل نسبيا في ملف vbxml يحتوي في النهاية
على بعض صيغ Razor!
كل
هذا يزيد من تعقيد كود الصفحة بدلا من تبسيطه، وهذا جعلني أتجه إلى حل آخر من خارج
الصندوق، مبنى على تطوير فكرة قالب
البيانات ForEach = "m" الذي شرحته من قبل، لكن لهدف مختلف تماما:
فقد
قررت تصميم صفحات Razor بدون استخدام أي من كود فيجوال بيزيك وسي شارب!
والفكرة
هنا ببساطة، أن أستخدم تيجان XML تعبر عن أوامر لغة البرمجة، ثم أترجم هذه التيجان في وقت التنفيذ
إلى كود سي شارب المناظر لها، وبهذا أحصل على صفحة cshtml
وأرسلها إلى Razor ليقوم بترجمتها!
وقد
نفذت هذه الفكرة بالفعل، وأسميتها ZML (الحرف Z من Razor
والحرفان ML من XML) وكتبت مترجم ZML في هذا القالب.. هذا
المترجم البسيط الذي كتبته في عجالة يفترض أنه يستلم صيغة ZML صحيحة
بدون أخطاء (لو صار لدينا محرر كود ل ZML فسيكون هو المسئول
عن تدقيق الصياغة)، وهو يتعامل حاليا مع عدد محدود من تيجان الأوامر، لكنها هي
الأكثر شيوعا.. وسأضيف مزيدا من الأوامر كلما احتجت إليها عمليا بإذن الله.. وهذه
الأوامر هي:
لاحظوا
أنني حاليا أستخدم ZML مع Vazor وبالتالي صار من الممكن تضمين كود ZML داخل
كود vbxml كما في هذا المثال:
تاج ZML
|
كود C# Razor الذي ينتجه
|
<page />
|
@page
|
<model type="mtype" />
|
@model mtype
|
<model type="List(Of
mtype)" />
|
@model List <
mtype >
|
<set object="obj" value="val" />
|
@{
obj = val;
}
|
<set object="ViewData['Title']" value="Test" />
|
@{
ViewData["Title"]
= "Test"
}
|
استخدام
قوسي فيجوال بيزيك:
<set object="ViewData('Message')"
value="OK" />
|
@{
ViewData["Message"]
= "Ok"
}
|
حالة
خاصة لتسهيل استخدام بيانات العرض:
Message="OK" />
|
@{
ViewData["Title"]
= "Test"
ViewData["Message"]
= "Ok"
}
|
<foreach var="m" in="Model">
block of zml code
</foreach>
|
@foreach(var
m in Model)
{
block of zml code
}
|
<if condition="cond">
block of zml code
</if>
|
@if(cond)
{
block of zml code
}
|
<if condition="cond1">
<then>
block of zml code
</then>
<elseif condition="cond2">
block of zml code
</elseif>
<else>
block of zml code
</else>
</if>
|
@if(cond1)
{
block of zml code
}
elseif(cond2)
{
block of zml code
}
else
{
block of zml code
}
|
<zml>
<model type="List(Of
WebApp1.Student)"/>
<h3 fff="">
Browse Students</h3>
<p>Select
from <%=
Students.Count %>
students:</p>
<p>Students
details:</p>
<ul>
<foreach var="m" in="Model">
<li>
Id: @m.Id<br/>
Name: @m.Name<br/>
<p>Grade:
@m.Grade</p>
</li>
</foreach>
</ul>
</zml>
لاحظ
أن كود vb المضمن داخل <%= %> لا يستخدم المعامل Model فهذا خاص فقط بصيغ ZML، وبدلا من هذا يتعامل كود فيجوال بيزيك مباشرة مع الخاصية Students
المعرفة في نفس الفئة.. يمكنك تجربة هذا الكود في المشروع WebApp1
الموجود في مستودع Vazor.
سأستخدم
ZML بإذن الله في تحويل كود مشروع الويب الذي ذكرته في أول الموضوع..
والجميل في الأمر أنني أستطيع أن أكتبها في صفحات cshtml مباشرة
، فكود ZML يخلو من كود فيجوال بيزيك، وبالتالي هو في نظر محرر صفحات cshtml مجرد
كود XML عادي!.. لكني أتمنى أن تتبنى ميكروسوفت ZML وتنشئ
له محررا خاصا بصفحات .zml حتى نحصل على الإكمال التلقائي لتيجان ZML مع فحص
سلامة صياغتها.. في هذه الحالة ستستفيد مشاريع VB.NET وF# من هذا
المصمم الجديد، وتكون مشكلتهما قد حلت!
هكذا
ستبدو صفحة كاملة مكتوبة بـ ZML:
<page />
<model type="CatalogModel"/>
<ViewData Title="zml
sample" Message="another
syntax" />
<div class="container">
<if condition="CatalogModel.CatalogItems.Any()">
<then>
<partial name="_pagination" for="CatalogModel.PaginationInfo" />
<div class="esh-catalog-items
row">
<foreach var="catalog" in="CatalogModel.CatalogItems">
<div class="esh-catalog-item
col-md-4">
<partial name="_product" for="@catalog" />
</div>
</foreach>
</div>
<partial name="_pagination" for="CatalogModel.PaginationInfo" />
</then>
<elseif condition="CatalogModel.Count>3">
</elseif>
<else>
<div class="esh-catalog-items
row">
THERE ARE NO RESULTS THAT MATCH
YOUR SEARCH
</div>
</else>
</if>
</div>
وهذا
هو كود cshtml المناظر لها:
@page
@model CatalogModel
@{
ViewData["Title"] =
"zml sample";
ViewData["Message"] =
"another syntax";
}
<div class="container">
@if (@Model.CatalogModel.CatalogItems.Any())
{
<partial name="_pagination" for="CatalogModel.PaginationInfo" />
<div class="esh-catalog-items
row">
@foreach (var catalog in
@Model.CatalogModel.CatalogItems)
{
<div class="esh-catalog-item
col-md-4">
<partial name="_product" for="@catalog" />
</div>
}
</div>
<partial name="_pagination" for="@Model.CatalogModel.PaginationInfo" />
}
elseif (CatalogModel.Count >
3)
{
}
else
{
<div class="esh-catalog-items
row">
THERE ARE NO RESULTS THAT MATCH YOUR
SEARCH
</div>
}
</div>
ليست هناك تعليقات:
إرسال تعليق
ملحوظة: يمكن لأعضاء المدونة فقط إرسال تعليق.