Memanfaatkan tag HTML menggunakan C #

Dalam proses selanjutnya menulis aplikasi web untuk ASP.NET MVC menggunakan Bootstrap, saya mendapati diri saya berpikir bahwa pembuatan tag HTML yang tak terelakkan dapat dikurangi. Ini bukan tentang seperangkat kontrol pengguna untuk memperluas Html. * Space, tetapi tentang apa yang terletak sedikit lebih jauh. Untuk tergesa-gesa, saya sarankan Anda melihat di sini (GitHub) , dan sisanya, selamat datang ke kucing.

Tantangan


Ada tag HTML yang berisi nama, kelas, gaya, atribut, dll. Di .NET, untuk pembuatan "manual" dari keindahan ini, diasumsikan menggunakan kelas TagBuilder dan secara bertahap mengisinya dengan meta yang diperlukan dan data yang adil.

Tapi!

Penggunaan kelas ini secara teratur bagi saya terasa terlalu suram. Konstan.

Berikut ini contoh tampilan elemen tombol standar:

<!-- HTML --> <button type="button" class="btn btn-success">Success</button> 

 // C# var tb = new TagBuilder("button"); tb.Attributes.Add("type", "button"); tb.AddCssClass("btn"); tb.AddCssClass("btn-success"); tb.SetInnerText("Success"); var htmlString = tb.ToString(TagRenderMode.Normal); 

Kami menambahkan di sini bahwa kadang-kadang tag HTML memerlukan penyatuan, yang berarti bahwa satu atau banyak * .InnerHtml dengan parameter diperlukan, yang masing-masing harus dibuat dengan cara yang sama - panjang-dimensi-langkah-demi-langkah - menjadi jelas bahwa Anda menginginkan sesuatu sesuatu yang kurang rutin.

Ini adalah bagaimana kelas TagDecorator lahir.

Masalah lain yang ingin saya selesaikan adalah sebagai berikut - untuk menyederhanakan pembuatan tag HTML, menjauh dari langkah-demi-langkah dan mengatur penyatuan alami hierarki HTML.

Solusi


Tautan: TagDecorator

Pada tahap awal, solusinya terdiri dari dua kelas, tetapi kemudian satu lagi ditambahkan ke mereka:

TagDecorator adalah kelas pekerja utama, yang bertanggung jawab untuk mengubah teks biasa menjadi kelas yang mewakili tag (TagWrapper), yang dapat ditambahkan ekstensi tambahan. Dalam contoh yang ada, ada kedua fungsi umum AddAttribute, AddCss, dan fungsi pribadi AddType, AddName, AddId - membuat atribut spesifik.

TagWrapper adalah kelas yang mewakili tag. Itu dibuat untuk sepenuhnya menjauh dari TagBuilder bila memungkinkan dan ekstensi baru di IntelliSense tidak bingung dengan sifat-sifat kelas TagBuilder.

Tag - kelas yang diperlukan untuk memisahkan tag awal / akhir untuk memungkinkan penerapan blok HTML framing yang digunakan dalam RazorView

 @using(Html.SuchExtension) { //... }. 

Contohnya


Pada contoh tombol yang ditunjukkan, keuntungan menggunakan TagDecorator tidak begitu jelas:

 var htmlString = "button".ToTag() .AddType("button") .AddCss(new[] {"btn", "btn-success"}) .SetText("Success") .ToString(); 

Tapi sekarang dengan contoh kartu Bootstrap - semuanya sudah menjadi jauh lebih menyenangkan bagi mata:

Menggunakan TagBuilder

 var divMain = new TagBuilder("div"); divMain.AddCssClass("card"); divMain.Attributes.Add("style", "width: 18rem;"); var img = new TagBuilder("img"); img.AddCssClass("card-img-top"); img.Attributes.Add("src", "..."); img.Attributes.Add("alt", "Card image cap"); var divBody = new TagBuilder("div"); divBody.AddCssClass("card-body"); var h = new TagBuilder("h5"); h.AddCssClass("card-title"); h.SetInnerText("Card title"); var p = new TagBuilder("p"); p.AddCssClass("card-text"); p.SetInnerText("Some quick example text to build on the card title and make up the bulk of the card's content."); var a = new TagBuilder("a"); a.Attributes.Add("href", "#"); a.AddCssClass("btn"); a.AddCssClass("btn-primary"); a.SetInnerText("Go somewhere"); divBody.InnerHtml += h.ToString(TagRenderMode.Normal); divBody.InnerHtml += p.ToString(TagRenderMode.Normal); divBody.InnerHtml += a.ToString(TagRenderMode.Normal); divMain.InnerHtml += img.ToString(TagRenderMode.Normal); divMain.InnerHtml += divBody.ToString(TagRenderMode.Normal); return divMain.ToString(TagRenderMode.Normal); 

Versi dengan TagDecorator
 var htmlString = "div".ToTag() .AddCss("card") .AddAttribute("style", "width: 18rem;") .InnerHtml(new [] { "img".ToTag() .AddCss("card-img-top") .AddAttributes(new[] {new[] {"src", "..."}, new[] {"alt", "Card image cap"}}), "div".ToTag() .AddCss("card-body") .InnerHtml(new [] { "h5".ToTag().AddCss("card-title").SetText("Card title"), "p".ToTag().AddCss("card-text").SetText("Some quick example text to build on the card title and make up the bulk of the card's content."), "a".ToTag().AddCss(new[] {"btn", "btn-primary"}).AddAttribute("href", "#").SetText("Go somewhere") }) }).ToString(); 

Hasil


Cons


Yang utama yang saya yakini adalah bahwa implementasi cascading kadang-kadang menggeser kode ke kanan, sering bergerak di luar visi pengembang, dan semakin kompleks hierarkinya, semakin kuat

Pro


+ Baris kode - dikurangi. Dalam elemen yang paling sederhana, ada kenaikan sekitar 1-2 baris, dalam pohon HTML yang kompleks - sekitar 1/3 secara analogi jika Anda menggunakan TagBuilder.

+ Visibilitas - Anda dapat dengan jelas melihat di mana dan seperti apa sarangnya. Semuanya intuitif secara hierarkis dan lebih mudah dipahami.

+ Diperpanjang - beberapa kasus / atribut tertentu diperlukan - cukup tambahkan Ekstensi. Diperlukan pemeriksaan kondisi - tambahkan Ekstensi.

Kemungkinan peningkatan


Pada awalnya, saya berpikir tentang membuat tag yang sepenuhnya khusus berdasarkan kelas-kelas ini yang hanya akan memungkinkan ekstensi tertentu di tooltip - misalnya, menghapus tooltip ekstensi AddReference di tag tombol, tetapi kemudian meninggalkan rencana ini demi universalitas. Tetapi secara umum - solusi ini sekarang sangat membantu saya dalam proyek saya.

Itu juga seharusnya membuat paket NuGet, tetapi karena kurangnya waktu - semuanya ditunda.

Source: https://habr.com/ru/post/id416459/


All Articles