Component Yapısı Nedir?
Component, tekrar tekrar kullanılabilen kod bloklarıdır, parçalarıdır. Pek çok web uygulama çerçevesinde bileşen (component) yapıları farklı şekillerde kullanılır. Örneğin Angular, component yapısının kullanıldığı bir web uygulama çerçevesidir. (web application framework)
Component Yapısı Nasıl Çalışır?
Bileşen (Component), genelde bir kodun bütününden alınır ve sonrasında tekrar tekrar kullanılır. Örneğin, bir web sayfanız var. Bir iletişim sayfası oluşturup iletişim formu eklemek istiyorsunuz. Bunun için yeni bir iletişim sayfası açıyorsunuz ve iletişim formunuzu, gerekli tasarımları yaptıktan sonra sayfanıza ekliyorsunuz. Aradan bir süre geçiyor ve aynı tasarımdaki formu bu sefer de ana sayfanıza eklemek istiyorsunuz. Component yapısı tam da burada hayatımızı kolaylaştırıyor. Hemen açıklayayım. Hiç bir yapı kullanmadığınız taktirde ana sayfanıza aynı formu eklemek için aynı HTML kodunu kopyalamanız gerekir. Bunu yaptık da ne sorun var diye düşünüyor olabilirsiniz. Sorun şu ki yarın bir gün siz formun tasarımında ya da işlevinde bir değişiklik yapıp kodunuzu değiştirirseniz, o kodu kopyaladığınız her yerde de değiştirmeniz gerekir. Bileşen yapısı olmadığında da her kopya için değişim yapmanız gerekir.
Daha spesifik bir örnek vereyim. Bir mobil uygulamanız var. Her sayfada aynı butonları kullanmanız gerekiyor. Hadi, hepsini kopyalayıp yapıştırdığınızı düşünelim. Sonrasında ise ani bir kararla tüm butonların işlevinde değişiklik yapılması gerekirse geçmiş olsun. Component yapısının tanımında tekrar tekrar kullanılabilen dememin sebebi de bu aslında. Aklınıza takılan yerler olduysa merak etmeyin. Birazdan bu örneklerden ilkini beraber kodlayacağız.
ASP.NET Core’da View Component Yapısı Nedir?
ASP.NET Core'da kod parçaları yani component’ler partial view ve view component yapılarıyla tutulabilir. View component yapıları, partial view’lere oldukça benzer olsa da onlardan daha işlevseldir. View componentler model binding ile kullanılmaz,. View componentlere gönderilen verilere bağlı olarak çalışırlar.
Yeterince edebiyat yaptığımıza göre hemen işe koyulalım ve view component yapılarını ASP.NET Core projelerinize nasıl entegre edebileceğinize bakalım.
View Component Nasıl Kullanılır?
Kodlama sırasında az evvel bahsettiğim iletişim formu örneği üzerinden yeni bir proje oluşturarak ilerleyeceğim. Bunun için Visual Studio 2022’yi kullanacağım ve Asp.NET Core 6.0 versiyonunda bir proje geliştireceğim. Siz de kendi projelerinizde benzer adımları izleyerek rahatlıkla view component yapılarını kullanabilirsiniz. Hatalar çıkarsa yorum kısmından gönderebilirsiniz.
Proje Kurulumu
İlk aşamada projeyi kuruyoruz. Projeniz varsa bu adımları atlayabilirsiniz tabi ki. 🙂 Projenizi kurduktan sonra başlangıç ekranıyla karşılaşacaksınız. Buradaki Index.cshtml dosyası bizim anasayfamız.
Reklam
İletişim Sayfası Oluşturalım
Index.cshtml dosyasını hızlıca kopyalayıp yeni bir view oluşturuyoruz. İsmini değiştiriyoruz ve Contact.cshtml yapıyoruz. Sonrasında Contact sayfamız için ContactModel oluşturuyoruz.
Contact.cshtml.cs dosyası içerisindeki modelin ismini değiştirmemiz gerekiyor. Eğer kopyalama işlemi sonrası değişiklik yapmazsak hata alacağız.
Reklam
İletişim Sayfasına HTML Form Ekleme
Contact.cshtml sayfasına girip içeriğini değiştirmeye başlayabiliriz. İlk önce modelimizi ContactModel ile değiştiriyoruz. Kafa karışıklığı oluşturmamaıs adına ViewData[’Title’]’ı da değiştirebilirsiniz.
Bu işlemlerden sonra Bootstrap kütüphanesinin kullanıldığı örnek bir HTML kodunu sayfama yapıştırıyorum.
@page
@model ContactModel
@{
ViewData["Title"] = "Contact Page";
}
<h1>İLETİŞİM FORMU</h1>
<hr />
<form class="row g-3">
<div class="col-md-12">
<label for="staticEmail2" class="visually-hidden">Email</label>
<input type="text" class="form-control" id="staticEmail2" placeholder="email@example.com">
</div>
<div class="col-md-12">
<label for="message" class="visually-hidden">Message</label>
<textarea type="password" class="form-control" id="message" placeholder="Message"></textarea>
</div>
<div class="col-md-12">
<button type="submit" class="btn btn-primary mb-3">Gönder</button>
</div>
</form>
En sonunda projemi başlatıp “/contact” adresine gittiğimde şöyle bir sayfayla karşılaşıyorum. Burası da bizim iletişim sayfamız.
Formu Anasayfaya Kopyalayalım
Örneğe bağlı kalacak olursak; formumuzu anasayfamıza yani Index.cshtml içerisine kopyalayalım.
Reklam
Aynı işleve ve tasarıma sahip olmasını istediğimiz iki formu da anasayfa ve iletişim sayfamıza koyduk. Hiç problem yok gibi. Tüh, iletişim formumuzdan isim verisini almayı unutmuşuz. İki kod için de ayrı ayrı eklememiz gerekiyor. Ekleyelim.
Bunun yüzlerce sayfa için değiştirilmesi gerektiğini düşünsenize. Büyük bir sorun. Hadi burada view component yapısını kullanarak işimizi kolaylaştıralım.
View Component Entegrasyonu Nasıl Yapılır?
Yazının bundan sonraki kısımlarında view component yapısının nasıl kullanıldığını aynı örneği devam ettirerek anlatacağım.
ViewComponents Dizini Oluşturma ve Sınıf Ekleme
Uygulamamızın altına ViewComponents isminde bir dizin oluşturalım. Dizine de bir sınıf oluşturalım. İletişim formunu bir bileşen içerisine taşıyacağımızdan dolayı bu sınıfa ContactForm.cs ismini veriyorum.
namespace ViewComponentLearningApp.ViewComponents { public class ContactForm { //ContactForm.cs sınıfı. Henüz view component değil !! } }
Reklam
ViewComponent Sınıfından Türetelim
ContactForm.cs sınıfını view component olarak kullanabilmemiz için ViewComponent sınıfından kalıtmamız gerekiyor. ViewComponent sınıfını kullanabilmemiz içinse using Microsoft.AspNetCore.Mvc; kodunu dosyamıza eklememiz gerekiyor.
using Microsoft.AspNetCore.Mvc;
namespace ViewComponentLearningApp.ViewComponents
{
public class ContactForm:ViewComponent
{
}
}
Bağımlılık Ekleme ve Invoke Fonksiyonu
Dependency injection işlemini yapalım. Ardından Invoke() fonksiyonunu ekleyelim. ViewComponent yapısında bu fonksiyonu bir bakıma Controller olarak düşünebilirsiniz. ViewComponent yapıları için gerekli olan verileri, modelleri buradan sağlayacağız.
using Microsoft.AspNetCore.Mvc;
namespace ViewComponentLearningApp.ViewComponents
{
public class ContactForm:ViewComponent
{
// Dependency Injection
// Bağımlılık ekleyelim.
public ContactForm()
{
}
// Senkron işlemler için Invoke ya da asenkron işlemler için InvokeAsync komutuyla
// view component sonucunu burada döndüreceğiz.
public IViewComponentResult Invoke()
{
return View();
}
// Asenkron işlemler için kullanabiliriz.
//public async Task<IViewComponentResult> InvokeAsync()
//{
// return View();
//}
}
}
ContactForm View Component’ini Oluşturalım
View component’ler varsayılan olarak belirli konumlarda bulunmalıdır. ViewComponent’ler için bu konumlar şunlardır: (Listedeki ContactForm sizin model isminize bağlı olarak değişecektir.)
- /Pages/Components/ContactForm/Default.cshtml
- /Pages/Shared/Components/ContactForm/Default.cshtml
- /Views/Shared/Components/ContactForm/Default.cshtml
Ben ikinci maddedeki şekilde dizinleme yapmayı tercih ettim. Burada atlanmaması gereken önemli bir kural var. View component’lerin varsayılan (default) görünümleri (views), view component’in ismindeki bir dizin içerisinde listelenmelidir. View component sınıfında herhangi bir isim belirtilmediğinde view dosyanızı Default.cshtml olarak oluşturmalısınız.
Konum listesindeki 2. madde için dizin yapısı fotoğraftaki gibi olmalıdır.
ContactForm içerisindeki Default.cshtml içerisine girelim ve önceden olan iletişim formumuzu yapıştıralım.
ViewComponent’i Razor Sayfalarımızda Kullanalım
View component’imiz hazır ve entegre edilmeyi bekliyor. Hemen devam edelim. Öncelikle biz hangi sayfalarda bu formu kullanmak istiyorduk? Contact ve Index.
Index içerisine nasıl entegre edebileceğimize bakalım. Sonrasında benzer işlemleri Contact sayfasına da uygulayacağız.
- Index.cshtml razor sayfasını açalım.
- Önceden eklediğimiz formu silelim ve yerine aşağıdaki kodu yapıştıralım. Bu kod, view component çağırmak için kullanılır.
@*View Component yapılarını entegre edebilmemiz için bu kod bloğunu kullanmamız gerekiyor.*@
@await Component.InvokeAsync("ContactForm")
İşte bu kadar. Artık basit bir view component’i nasıl kullanabileceğinizi biliyorsunuz.
Reklam
Farklı İsimlerde View Component Oluşturma
Basit bir view component oluşturduk. Peki aynı modele ihtiyaç duyan ya da sadece tasarımsal olarak ayrışan view component’leri nasıl oluşturabiliriz? Örneğin, e-posta girdisi almadığımız bir iletişim formunu da oluşturalım.
-
ContactForm dizini içerisine Default.cshtml’den farklı bir isimde view oluşturalım. Ben adını WithoutEmail.cshtml yaptım.
-
ContactForm ismindeki view component’imizi şu şekilde revize edelim:
using Microsoft.AspNetCore.Mvc; namespace ViewComponentLearningApp.ViewComponents { public class ContactForm:ViewComponent { public ContactForm() { } // "viewName" parametresiyle hangi isimde bir View Component çağıracağımız belirliyoruz. // viewName="Default" yapma sebebimse herhangi bir parametre olmadığında Default.cshtml'yi çağırması. // Bunu if else koşullarıyla da yapabilirsiniz ama çok uzatabilir. public IViewComponentResult Invoke(string viewName="Default") { return View(viewName); } } }
// Ya da bu şekilde using Microsoft.AspNetCore.Mvc; namespace ViewComponentLearningApp.ViewComponents { public class ContactForm:ViewComponent { public ContactForm() { } public IViewComponentResult Invoke(string viewName) { // View Name yoksa Default çağrılacak. if (viewName == null) { return View(); } // viewName paramtresi gönderildiyse o parametrenin isminde bir component çağrılacak. return View(viewName); } } }
-
Şimdi tek yapmamız gereken istediğimiz view component’in ismini göndermek.
@await Component.InvokeAsync("ContactForm", new { viewName = "WithoutEmail"})
Component’e viewName parametresini göndermediğinizde varsayılan olarak Default.cshtml dosyası çağrılır.
View Componente Model Gönderme
Benzer yöntemi kullanarak view component’imize bir model gönderelim.
-
Contact.cs isminde bir model oluşturalım.
using Microsoft.AspNetCore.Mvc; namespace ViewComponentLearningApp.ViewComponents { public class Contact { public string? Name { get; set; } public string? Email { get; set; } public string? Message { get; set; } } }
-
Invoke() fonksiyonuna parametre olarak ContactViewComponentModel verelim..
using Microsoft.AspNetCore.Mvc; namespace ViewComponentLearningApp.ViewComponents { public class ContactForm:ViewComponent { public ContactForm() { } // Varsayılan bir değeri olmayan parametreleri varsayılan değer verilmiş, viewName gibi, parametrelerin gerisine yazmalısınız. public IViewComponentResult Invoke(ContactViewComponentModel model, string viewName="Default") { // ilk parametre view adı - ikinci parametre: model return View(viewName, model); } } }
-
Razor sayfalarımızda view component’i çağırdığımız kod bloklarında bir değişiklik yapalım ve modeli gönderelim. İlk kod bloğu aynı satırda nasıl dahil edileceğini, ikinci kod bloğuysa harici olarak nasıl dahil edileceğini gösteriyor.
@await Component.InvokeAsync("ContactForm", new { viewName = "WithoutEmail", model = new ViewComponentLearningApp.ViewComponentModel.ContactViewComponentModel()})
@{ ViewComponentLearningApp.ViewComponentModel.ContactViewComponentModel farkliSatirda = new ViewComponentModel.ContactViewComponentModel() { Name = "Ömer", Email = "info@ofcskn.com", Message = "iyi kodlamalar!" }; } @await Component.InvokeAsync("ContactForm", new { viewName = "WithoutEmail", model = farkliSatirda})
ViewComponent’in Faydaları Nelerdir?
- Tekrarlanan kodları merkezileştirir. Değişim, revize etme gibi pek çok işlemde kolaylık sağlar.
- Farklı tasarımlarda olan ama aynı modelleri kullanan view dosyaları oluşturulabilir. Örneğin, iki farklı tasarımda iletişim formu kullanabilirsiniz ve aralarında geçiş yapabilirsiniz.
- Enerji ve zaman tasarrufu sağlar. Tekrarın önüne geçildiğinden işimizi kolaylaştırır.
- Kendi başına bir controller gibi çalıştığından model göndermeye ihtiyaç duymaz. Sadece parametre gönderilmesi yeterli olur.
View Component ve Partial View Farkı
Partial view bir modelle kullanıldığında o modelin servisler ya da controller aracılığıyla doldurulması gerekir. Bu da her partial view kullanıldığında bir servisin eklenmesi ya da modelin controller’da doldurulması demek oluyor. Aksine view component, bir controller gibi çalıştığından her view component için harici bir model gönderilmesine ihtiyaç kalmaz. Model zaten view component’in Invoke() fonksiyonu içerisinde doldurulur.
ASP.NET Core projelerinizde view component yapısının ne olduğundan ve nasıl kullanabileceğinizden örnek kodlar vererek bahsettim. Fotoğraflarda, kodlarda veya yazı da anlaşılmayan yerler olduysa yorumlar kısmından iletebilirsiniz. Kendinize iyi bakın. Klavyenize sağlık. 🙂
hasan
8.10.2023hocam elimdeki temayı _layout.cshtml içine attım. menu her sayfada aynı olacağı için onları veritabanından dinamik doldurup <partial name="_menu"> şeklinde _layout.cshtml içine bir türlü çağıramadım. @model etiketini kaldırınca geliyor. ama bu kez dinamik olmuyor. kafam çok karıştı.
Ömer
12.10.2023<partial name="_menu" model="MenuModel"> şeklinde modeli tanımlamadığın taktirde partial view hata verecektir. Onu düzeltirsen sorun çözülür. @model MenuModel etiketinin de _layout.cshtml dosyası içerisinde tanımlanmış olması gerek tabi