المتابعون للمدونة

الثلاثاء، 2 أبريل 2019

Vazor Pages

Vazor Pages
 
نجحت بفضل الله في إنشاء مشروع Razor Pages بفيجوال بيزيك يستخدم vbxml كود لتكوين الصفحات.. لاحظوا أن مشاريع Razor Pages مختلفة عن مشاريع MVC، بسبب الاختلاف في تنظيم المشروع وطريقة عمله، فشلت في تشغيل نظام الملفات التخيلي بنفس الطريقة التي استخدمته بها في مشاريع MVC.. لهذا قررت أن أجرب أولا العمل بدونه، فأنشأت هذا المشروع، وهو يستخدم حيلة بسيطة، حيث أبقيت Index.cshtml في المشروع لكن جعلتها شبه فارغة، وحقنت كود vbxml فيها من خلال الخاصية Model.VbXml بالكود التالي:
@Html.Raw(Model.VbXml)
حيث تقوم الوسيلة المساعدة  Html.Rawبإضافة النص المرسل إليها في الصفحة باعتباره كود HTML خام لا يجب معالجته بأي شكل بل يوضع كما هو.. بهذه الحيلة جعلنا صفحة cshtml مجرد صدفة فارغة ووضعنا فيها المجتوى الذي أنتجناه بفيجوال بيزيك!
وقد عمل المشروع بنجاح، لهذا قررت تنفيذ نفس الفكرة في مشروع من النوع MVC، وقد عمل أيضا بنجاح!
هذه الفكرة بسيطة للغاية، وتجعل كتابة المشروع أسرع بسبب عدم الاحتياج لكل الكود اللازم لتشغيل Vazor، لكن فيها مشكلتان:

1- لكل صفحة، سيكون لديك ملف cshtml ودالة لإنتاج vbxml (أنا أضعها في ملف مستقل لحسن تنظيم المشروع).
2- استخدام كود HTML خام بواسطة الوسيلة Html.Raw يمنعك من استخدام أي أدوات مساعدة مثل Tag Helpers أو استخدام @RenderBody() أو @RenderSection وغيرها من الأكواد المساعدة التي ليست أكواد HTML أصلية، حيث سيتم اعتبارها مجرد نصوص ولن يعالجها Razor وستظهر في المتصفح بنصها!.. هذا هو السبب الذي يجعل من غير الممكن تنفيذ هذه الفكرة من الصفحة التنسيقية -Layout.cshtml لأنها تحتوي على العديد من الأكواد المساعدة والرموز التي لا تصلح ككود HTML!.. عامة هذا عيب بسيط، فالصفحات المشتركة بين كل صفحات الموقع لا تحتوي في الغالب على كود سي شارب ولا حاجة لتحويلها إلى كود xml لأنه سيكون هو نفس الكود تقريبا!
 
لهذا جربت طريقة أخرى لتشغيل نظام مزود الملفات التخيلية في مشاريع Razor Pages في هذا المشروع، وهي تطوير لطريقة حقن الكود في صفحة cshtml ولكني هذه المرة لا أحقنه ككود خام، بل أحقنه كصفحة كود جزئية Partial Page ليقوم Razor بترجمتها.. هذه الصفحة الجزئية لن تكون صفحة حقيقية ولكن سأجعل نظام مزود الملفات التخيلية يرسل كود vbxml على أنه هذه الصفحة الجزئية (كما شرحت في الموضوع السابق).. لفعل هذا، أضفت الخاصية ViewNam لفئة قالب الصفحة، واستخدمتها لتسجيل صفحة vbxml في الخريطة، ووضعت في هذه الخاصية الاسم المتفرد الذي تم إعطاؤه للصفحة التخيلية:
Public ReadOnly Property ViewName As String
        Get
            Dim iv = IndexView.CreateInstance(Students, ViewData)
            Return Vazor.VazorViewMapper.Add(iv)
        End Get
End Property
ثم استخدمت هذه الخاصية لحقن هذه الصفحة التخيلية كصفحة جزئية ضمن صفحة cshtml:
@Html.Partial(Model.ViewName + ".cshtml")
وبهذا عمل المشروع بشكل طبيعي، وصار بإمكانك كتابة كود مساعد تريده ضمن كود vbxml.
كما يمكنك حذف صفحات cshtml المشتركة وكتابتها بكود vbxml لكن عليك تسجيلها في فئة البداية startup بكود كالتالي:
Vazor.VazorViewMapper.AddStatic(New LayoutView())
وقد أرسلت أطلب من فريق ASP.NET Core حل بعض المشاكل في مشاريع Razor Pages ولو فعلوا فسيكون بإمكاننا التخلص من صفحات cshtml التي تركناها لنحقن فيها الصفحات الجزئية، ليصير الأمر أسهل وأكثر اختصارا.
 
والآن بما أننا شغلنا Vazor في مشاريع RAzor Pages فقد صار من الممكن استخدمه أيضا في مشاريع Blazor التجريبية!
وهذا يعني أن الطريق مفتوح أمام مبرمج فيجوال بيزيك لكتابة كل مشاريع ASP.NET Core.. ولديه الآن ثلاثة بدائل لتصميم صفحات العرض، وإمكانيات هائلة غير مسبوقة:
1- استخدام صفحات cshtml تحتوي على كود سي شارب، وستعمل بشكل صحيح!
2- استخدام صفحات cshtml فارغة وحقنها بكود vbxml!
3- حذف صفحات cshtml واستخدام صفحات vbxml تخيلية!
4- الجميل في الأمر أنك تستطيع أن تستخدم هذه الطرق الثلاثة معا في نفس المشروع ليحتوي على مزيج من الصفحات مختلفة الأنواع!
5- بل يمكنك أن تستخدم داخل كود vbxml، متغيرات Razor (مثل @ViewData["Title"] مع الالتزام بصيغة سي شارب هنا)!
6- بل والأغرب أنك تستطيع إضافة مقاطع من كود سي شارب داخل كود vbxml لكن مع ملاحظة أن فيجول بيزيك ستتعامل معها كأنها نصوص عادية، لكن Razor هو من سيترجمها!
7- وأبعد من هذا وذاك، فإن تصميم الصفحة داخل فئة مكتوبة بكود فيجوال بيزيك يمنحك إمكانيات أبعد مما يصل إليه خيالك، لأنك تستطيع إضافة مرحلة وسيطة بين كود vbxml وكود cshtml تنفذ فيها ما يحلو لك من معالجة على الصفحة.. على سبيل المثال، هذا الكود من ابتكاري (ستجده في هذا الملف):
<ul>
    <li ForEach="m">
       Id: <m.Id/><br/>
       Name: <m.Name/><br/>
       <p>Grade: <m.Grade/></p>
    </li>
</ul>
كود vbxml السابق ينتج كود HTML التالي:

  

  •       Id: 1
          Name: Adam<br/>
          Grade:  69
      

      

  •       Id :  2
          Name: Mark<br/>
          Grade:  80
      

      

  •       Id :  3
          Name: Tom<br/>
          Grade:  51
      

    </ul>
    كل ما فعلته هو أنني كتبت قالبا لعرض بيانات تلميذ واحد، ووضعت السمة ForEach="m" في تاج العنصر الذي يحتوي على أدوات العرض (وهو هنا عنصر القائمة li).. لاحظ أن m هو اسم متغير يمكنك أن تضع مكانه أي اسم آخر.
    ويتم تطبيق هذا القالب على قالب البيانات Model المستخدم مع الصفحة.. في حالتنا هنا سيكون قائمة تحتوي على بيانات عدة تلاميذ.. وقد كتبت دالة اسمها ParseTemplate يمكنك أن ترسل إليها كود XML وكائنا يحتوي على قائمة البيانات التي تريد عرضها (يجب أن يكون هذا الكائن من أي نوع يمثل الواجهة IEnumerable مثل المصفوفة أو القائمة List).. هذه الوسيلة تستخدم الانعكاس Reflection لمعرفة الخصائص الموجودة في كائن البيانات، وتبحث في كود XML عن العنصر الذي فيه السمة ForEach وتكرره بعدد عناصر القائمة، وتأخذ قيمة السمة  ForEach (اسم المتغير مثل m)، وتبحث عن الخصائص المستخدم  معه (مثل m.Id) وتعوض عن قيمها المناظرة لكل عنصر في القائمة!.. ستجد كود هذه الوسيلة في هذا الملف.. وقد عرفت الوسيلة ParseTemplate كوسيلة إضافية Extension Method للفئة XElement حتى يمكن استخدامها هكذا مباشرة:
    Dim html = GetVbXml().ParseTemplate(students)
    بمثل هذه الطريقة dمكنك إضافة أي أكواد خاصة أو معالجات تريدونها على كود vbxml قبل تسليمه إلى Razor!
    أنا عن نفسي معجب بالصيغة:
    <ul>
        <li ForEach="m">
           Id: <m.Id/><br/>
           Name: <m.Name/><br/>
           <p>Grade: <m.Grade/></p>
        </li>
    </ul>
    وأراها أكثر اختصارا من كود فيجوال بيزيك المضمن في دالة فورية داخل xml بل حتى من كود سي شارب المناظر في Razor:
    <ul>
       @foreach (var m in Model)
       {
        <li>
           Id: <m.Id/><br/>
           Name: <m.Name/><br/>
           <p>Grade: <m.Grade/></p>
        </li>
       }
    </ul>
    مع ملاحظة أن القالب الخاص بي مصمم للتعامل مع المستوى الأول من عناصر الكائن، ولا يسمح بالتعامل مع مستويات أعمق من الخصائص المتداخلة.. كما أنه مصمم لعرض قيم الخصائص مباشرة بدون إجراء أي عمليات إضافية عليها.. لو أردت أن تسمح بهذا، فلديك الحرية في تعديل الكود ليناسب احتياجاتك، لكني أرى أنه سيصير معقدا، والأسهل في مثل هذه الحالات (وهي نادرة) أن تستخدم كود فيجوال بيزيك مباشرة.
     
    سأكتفي بهذا الآن، وسأشرح في موضوع تال بإذن الله، تفاصيل أكثر عن استخدام Vazor في مشاريع MVC و Razor Pages.. فيجوال ستديو 2019 ستصدر اليوم بإذن الله، ونريد أن نبدأ في إنشاء مشاريع فيجوال بيزيك بتقنية Vazor عليها.
     

    ليست هناك تعليقات:

    إرسال تعليق

    ملحوظة: يمكن لأعضاء المدونة فقط إرسال تعليق.

    صفحة الشاعر