Son zamanlarda Mantıksız şablon olduğu iddia edilen bıyıkla karşılaştım .
Bununla birlikte, neden Mantıksız bir şekilde tasarlandığına dair bir açıklama yoktur. Başka bir deyişle, Mantıksız şablonun avantajı nedir?
Son zamanlarda Mantıksız şablon olduğu iddia edilen bıyıkla karşılaştım .
Bununla birlikte, neden Mantıksız bir şekilde tasarlandığına dair bir açıklama yoktur. Başka bir deyişle, Mantıksız şablonun avantajı nedir?
Yanıtlar:
Başka bir deyişle, kendinizi ayağınıza vurmanızı engeller. Eski JSP günlerinde, JSP dosyalarının Java kodu ile serpiştirilmesi çok yaygındı, bu da kodunuzu dağınık hale getirdiğiniz için yeniden düzenleme işlemini çok daha zor hale getiriyordu.
Şablonlarda mantığı tasarım gereği engellerseniz (bıyık gibi), mantığı başka bir yere koymak zorunda kalacaksınız, böylece şablonlarınız derli toplu kalacaktır.
Diğer bir avantaj, endişelerin ayrılması açısından düşünmeye zorlanmanızdır: denetleyiciniz veya mantık kodunuz , kullanıcı arayüzüne veri göndermeden önce veri masajı yapmak zorunda kalacaktır . Daha sonra şablonunuzu başka bir şablonla değiştirirseniz (diyelim ki farklı bir şablon oluşturma motoru kullanmaya başladınız), geçiş kolay olacaktır çünkü yalnızca UI ayrıntılarını uygulamanız gerekir (şablonda mantık olmadığı için unutmayın).
Kanımca neredeyse yalnız olduğumu hissediyorum, ama kesinlikle karşı kamptayım. Şablonlarınızdaki iş mantığının olası karışımının, programlama dilinizin tüm gücünü kullanmamak için yeterli neden olduğuna inanmıyorum.
Mantıksız şablonlar için olağan argüman, programlama dilinize tam erişiminiz varsa, bir şablonda yer olmayan mantığı karıştırabileceğinizdir. Bunu, eti dilimlemek için kaşık kullanmanız gerektiği gerekçesine benzetiyorum çünkü bıçak kullanırsanız kendinizi kesebilirsiniz. Bu çok doğrudur ve yine de dikkatli de olsa ikincisini kullanırsanız çok daha üretken olursunuz.
Örneğin, bıyık kullanan aşağıdaki şablon parçasını düşünün :
{{name}}:
<ul>
{{#items}}
<li>{{.}}</li>
{{/items}}
</ul>
Bunu anlayabiliyorum, ancak aşağıdakileri ( alt çizgi kullanarak ) çok daha basit ve doğrudan buluyorum :
<%- name %>:
<ul>
<% _.each(items, function(i){ %>
<li><%- i %></li>
<% }); %>
</ul>
Bununla birlikte, mantıksız şablonların avantajları olduğunu anlıyorum (örneğin, birden çok programlama diliyle değişiklik olmadan kullanılabilirler). Bu diğer avantajların çok önemli olduğunu düşünüyorum. Mantıksız doğalarının onlardan biri olduğunu sanmıyorum.
name
ve items
JavaScript içerebilir.
Bıyık mantıksız mı?
Bu değil mi:
{{#x}}
foo
{{/x}}
{{^x}}
bar
{{/x}}
Buna oldukça benzer mi?
if x
"foo"
else
"bar"
end
Ve değil bu oldukça benzer (okuyun: neredeyse bir tanım) sunum mantığı?
if x > 0 && x < 10
) ... Yani, Mustache'i mantıkla veya mantıksız kullanmak mümkün olsa da, bu size kalmış. Sonuçta, bu sadece bir araç.
Mantıksız şablon, nasıl doldurduğunuz değil, doldurmanız gereken delikler içeren bir şablondur. Mantık başka bir yere yerleştirilir ve doğrudan şablona eşlenir. Kaygıların bu ayrımı idealdir çünkü o zaman şablon farklı mantıkla veya hatta farklı bir programlama dili ile kolayca oluşturulabilir.
Gönderen bıyık kılavuzu :
Buna "mantıksız" diyoruz çünkü hiçbir if ifadesi, else cümlesi veya for döngüsü yok. Bunun yerine sadece etiketler vardır. Bazı etiketler bir değerle değiştirilir, bazıları hiçbir şeyle ve diğerleri bir dizi değerle değiştirilir. Bu belgede, farklı Mustache etiketi türleri açıklanmaktadır.
Madalyonun diğer yüzü, iş mantığını sunumun dışında tutmak için umutsuz bir girişimde, modele çok sayıda sunum mantığı koymanızdır. Genel bir örnek, "tek" ve "çift" sınıflarını bir tablodaki alternatif satırlara koymak isteyebileceğiniz olabilir, bu, görünüm şablonunda basit bir modulo operatörü ile yapılabilir. Ancak, görünüm şablonunuz bunu yapmanıza izin vermiyorsa, model verilerinizde yalnızca hangi satırın tek veya çift olduğunu değil, şablon motorunuzun ne kadar sınırlı olduğuna bağlı olarak, modelinizi kirletmeniz bile gerekebilir. gerçek CSS sınıflarının isimleriyle. Görünümler, Modellerden ayrı, tam nokta olmalıdır. Ancak Modeller aynı zamanda Görünümden bağımsız olmalıdır ve bu "mantıksız" şablon motorlarının çoğu size unutturur. Mantık her iki yere de gider,aslında nereye gideceğine doğru bir şekilde karar verir. Bir sunum endişesi mi yoksa bir iş / veri sorunu mu? % 100 bozulmamış görüşlere sahip olma çabasıyla, kirlilik sadece daha az görünen ancak eşit derecede uygunsuz başka bir yere iniyor.
Diğer yönde büyüyen bir hareket var ve umarım işler daha makul orta zeminde bir yere odaklanır.
Şablonlarınızı daha temiz hale getirir ve sizi mantığı düzgün şekilde birim testinin yapılabileceği bir yerde tutmaya zorlar.
Bu konuşma, orta çağ rahiplerinin bir iğnenin ucuna kaç meleğin sığabileceği konusunda tartışmaları gibi geliyor. Başka bir deyişle, dindar, beyhude ve yanlış odaklanmaya başlıyor.
Kısa rant ortaya çıkıyor (görmezden gelmekten çekinmeyin)
Okumaya devam etmek istemiyorsanız .. Yukarıdaki konuya kısa cevabım: Mantıksız şablonlara katılmıyorum. Bunu aşırılığın bir programlama biçimi olarak düşünüyorum. :-) :-)
Şimdi rantım tüm hızıyla devam ediyor: :-)
Bence birçok fikri aşırıya götürdüğünüzde, sonuç gülünç oluyor. Ve bazen (yani bu konu) sorun, "yanlış" fikri aşırıya götürmemizdir.
Tüm mantığı görünümden çıkarmak "gülünç" ve yanlış fikirdir.
Bir an geri çekilin.
Kendimize sormamız gereken soru, mantığı neden kaldıralım? Kavram, açıkça endişelerin ayrılmasıdır . Görünüm işlemeyi mümkün olduğunca iş mantığından ayrı tutun. Bunu neden yapıyorsun? Görünümleri değiştirmemize izin verir (farklı platformlar için: mobil, tarayıcı, masaüstü vb.) Ve kontrol akışını, sayfa sırasını, doğrulama değişikliklerini, model değişikliklerini, güvenlik erişimini vb. Daha kolay değiştirmemize olanak tanır. görünümlerden (özellikle web görünümlerinden) kaldırıldığında, görünümleri çok daha okunabilir ve dolayısıyla daha sürdürülebilir hale getirir. Bunu anlıyorum ve buna katılıyorum.
Bununla birlikte, öncelikli odak, endişelerin ayrılması üzerinde olmalıdır. % 100 mantıksız görünümler değil. Görünümler içindeki mantık, "modelin" nasıl işleneceği ile ilgili olmalıdır. Bana kalırsa, görüşlerdeki mantık gayet iyi. İş mantığı olmayan bir görünüm mantığına sahip olabilirsiniz.
Evet, kod mantığı ve görünüm mantığının çok az ayrıldığı veya hiç ayrılmadığı JSP'ler, PHP veya ASP sayfaları yazdığımız günlerde, bu web uygulamalarının bakımı tam bir kabustu. İnanın bana biliyorum, bu canavarlıklardan bazılarını yarattım ve sürdürdüm. Bu bakım aşamasında, meslektaşlarımın ve arkadaşlarımın yollarındaki hatasını (içgüdüsel olarak) gerçekten anladım. :-) :-)
Böylece yükseklerden gelen karar (endüstri uzmanları) oldu, web uygulamalarınızı önden görünüm denetleyicisi (işleyicilere veya eylemlere gönderilen [web çerçevenizi seçin]) gibi bir şey kullanarak yapılandırmanız gerekir ve görünümleriniz kod içermemelidir . Görüşler aptal şablonlar haline gelecekti.
Bu nedenle, genel olarak yukarıdaki düşünceye katılıyorum, ferman maddelerinin ayrıntıları için değil, daha çok görüş ve iş mantığı arasındaki endişelerin ayrılması arzusu olan fermanın arkasındaki motivasyon için.
Dahil olduğum bir projede mantıksız görüş fikrini gülünç aşırılığa kadar izlemeye çalıştık. Model nesnelerini html'de oluşturmamıza izin verecek, kendi geliştirdiğimiz bir şablon motorumuz vardı. Basit bir jeton tabanlı sistemdi. Çok basit bir sebepten dolayı korkunçtu. Bazen bir görünümde, bu küçük HTML pasajını görüntüleyip görüntülememeye karar vermemiz gerekiyordu .. Karar genellikle modeldeki bir değere dayanır. Görünümde kesinlikle hiçbir mantığınız yoksa, bunu nasıl yaparsınız? Yapamazsın. Bu konuda mimarımızla bazı önemli tartışmalarım oldu. Görüşlerimizi yazan front-end HTML kullanıcıları, bununla karşılaştıklarında tamamen durdular ve başka türlü basit hedeflerine ulaşamadıkları için çok stresliydi. Bu yüzden şablonlama motorumuza basit bir EĞER ifadesi kavramını getirdim. Size ortaya çıkan rahatlamayı ve sükuneti tarif edemem. Sorun, şablonlarımızdaki basit bir IF-Statement konseptiyle çözüldü! Aniden şablonlama motorumuz iyi hale geldi.
Peki bu aptal stresli duruma nasıl girdik? Yanlış hedefe odaklandık. Kuralı takip ettik, görüşlerinizde herhangi bir mantığınız olmamalıdır. Bu yanlıştı. Bence "pratik kural", görüşlerinizdeki bu mantık miktarını en aza indirmek olmalıdır. Çünkü bunu yapmazsanız, yanlışlıkla iş mantığının görüşe girmesine izin verebilirsiniz - bu da endişelerin ayrılmasını ihlal eder.
"Görünümlerde mantığınız olmamalı" dediğinizde, "iyi" bir programcı olduğunuzu anlamanın kolaylaştığını anlıyorum. (Eğer iyilik ölçütünüz buysa). Şimdi yukarıdaki kuralla orta karmaşıklıkta bir web uygulaması uygulamayı deneyin. O kadar kolay yapılmaz.
Benim için görüşlerdeki mantık kuralı o kadar net değil ve açıkçası olmasını istediğim yer burası.
Görünümlerde çok fazla mantık gördüğümde, bir kod kokusu tespit ediyorum ve mantığın çoğunu görünümlerden çıkarmaya çalışıyorum - iş mantığının başka bir yerde yaşamasını sağlamaya çalışıyorum - endişeleri ayırmaya çalışıyorum. Ancak, tüm mantığı görüş alanından kaldırmamız gerektiğini söyleyen insanlarla sohbet etmeye başladığımda , bana göre, bu sadece fanatizm kokusu, çünkü yukarıda anlattığım gibi durumlarda son bulabilirsin.
Rantımı bitirdim. :-)
Şerefe,
David
Mantıksız şablonlar için bulduğum en iyi argüman, hem istemcide hem de sunucuda tam olarak aynı şablonları kullanabilmenizdir. Bununla birlikte, gerçekten mantıksız olmanız gerekmez, sadece kendi "dili" olan bir tane var. Bıyığın anlamsız bir şekilde sınırlandırdığından şikayet edenlere katılıyorum. Teşekkürler, ama ben büyük bir çocuğum ve şablonlarımı yardımınız olmadan temiz tutabilirim.
Diğer bir seçenek de, hem istemci hem de sunucuda desteklenen bir dil kullanan bir şablon sözdizimi bulmaktır, yani sunucuda javascript ya node.js kullanarak ya da therubyracer gibi bir şey aracılığıyla bir js yorumlayıcısı ve json kullanabilirsiniz.
O halde, şimdiye kadar verilen örneklerden çok daha temiz olan ve harika çalışan haml.js gibi bir şey kullanabilirsiniz.
Bir cümlede: Mantıksız, şablon motorunun kendisinin daha az karmaşık olduğu ve bu nedenle daha küçük bir ayak izine sahip olduğu ve beklenmedik şekilde davranması için daha az yol olduğu anlamına gelir.
Soru eski ve cevaplanmış olsa da, 2 ¢ eklemek istiyorum (bu bir rant gibi gelebilir, ancak öyle değil, sınırlamalar ve kabul edilemez hale geldiklerinde).
Bir şablonun amacı, iş mantığını gerçekleştirmek değil, bir şeyi ortaya çıkarmaktır. Şimdi, bir şablonda yapmanız gereken şeyi yapamamak ile bunlarda "iş mantığı" arasında ince bir çizgi var. Mustache konusunda gerçekten olumlu olsam ve kullanmaya çalışsam da oldukça basit durumlarda ihtiyacım olanı yapamıyordum.
Verilerin "masajı" (kabul edilen cevapta kelimeleri kullanmak için) gerçek bir sorun haline gelebilir - basit yollar bile desteklenmez (Handlebars.js'nin ele aldığı bir şey). Veri görüntüleme verisine sahipsem ve şablon motorum çok sınırlayıcı olduğu için bir şeyi her işlemek istediğimde ince ayar yapmam gerekiyorsa, sonunda bu yardımcı olmaz. Ve bıyığın kendisi için iddia ettiği platform bağımsızlığının bir kısmını yener; Her yerde masaj mantığını kopyalamalıyım.
Bununla birlikte, biraz hayal kırıklığından sonra ve diğer şablon motorlarını denedikten sonra, .NET Razor şablonlarından esinlenen bir sözdizimi kullanan kendi (... yine başka bir ...) oluşturduk. Sunucuda ayrıştırılır ve derlenir ve basit, kendi kendine yeten bir JS işlevi (aslında RequireJS modülü olarak) oluşturur; bu, şablonu "yürütmek" için çağrılabilir ve sonuç olarak bir dize döndürür. Brad tarafından verilen örnek, motorumuzu kullanırken şöyle görünecektir (şahsen, hem Bıyık hem de Alt Çizgi'ye kıyasla kolayca daha üstün buluyorum):
@name:
<ul>
@for (items) {
<li>@.</li>
}
</ul>
Bir başka mantıksız sınırlama, Mustache ile parsiyelleri ararken bize çarptı. Kısımlar Mustache tarafından desteklenirken, ilk önce aktarılacak verileri özelleştirme imkanı yoktur. Bu yüzden, modüler bir şablon oluşturup küçük blokları yeniden kullanmak yerine, içinde tekrarlanan kodlar olan şablonlar yapacağım.
Bunu, JPath adını verdiğimiz XPath'den ilham alan bir sorgu dili uygulayarak çözdük. Temel olarak, çocuklara geçiş yapmak için / kullanmak yerine noktaları kullanırız ve sadece dize, sayı ve boole değişmezleri değil, aynı zamanda nesneler ve diziler de desteklenir (tıpkı JSON gibi). Dil, yan etkisizdir (şablon oluşturma için bir zorunluluktur) ancak yeni değişmez nesneler oluşturarak verileri gerektiği gibi "masaj yapmaya" izin verir.
Özelleştirilebilir başlıklar ve satırlardaki eylemlere bağlantılar içeren bir "veri ızgarası" tablosu oluşturmak ve daha sonra jQuery kullanarak dinamik olarak satırlar eklemek istediğimizi varsayalım. Bu nedenle, kodu çoğaltmak istemiyorsam satırların kısmi olması gerekir. Hangi sütunların oluşturulacağı gibi bazı ek bilgiler görünüm modelinin bir parçasıysa ve her satırdaki bu eylemler için aynıysa sorun burada başlar. Şablonumuzu ve sorgu motorumuzu kullanan bazı gerçek çalışma kodları aşağıda verilmiştir:
Tablo şablonu:
<table>
<thead>
<tr>
@for (columns) {
<th>@title</th>
}
@if (actions) {
<th>Actions</th>
}
</tr>
</thead>
<tbody>
@for (rows) {
@partial Row({ row: ., actions: $.actions, columns: $.columns })
}
</tbody>
</table>
Satır şablonu:
<tr id="@(row.id)">
@for (var $col in columns) {
<td>@row.*[name()=$col.property]</td>
}
@if (actions) {
<td>
@for (actions) {
<button class="btn @(id)" value="@(id)">@(name)...</button>
}
</td>
}
</tr>
JS kodundan çağrı:
var html = table({
columns: [
{ title: "Username", property: "username" },
{ title: "E-Mail", property: "email" }
],
actions: [
{ id: "delete", name: "Delete" }
],
rows: GetAjaxRows()
})
İçinde herhangi bir iş mantığı bulunmamakla birlikte yeniden kullanılabilir ve yapılandırılabilir ve ayrıca yan etkisizdir.
row
Statik adlar kullanmak yerine nesneden alınacak özellik adlarının dinamik olarak belirlenmesine izin verir . Örneğin, eğer $col.property == 'Something'
o zaman bu, içeriğini verir row.Something
.
İşte karakter sayımlarıyla bir liste oluşturmanın 3 yolu. İlki ve en kısa olanı hariç tümü mantıksız şablon dillerindedir ..
CoffeeScript ( Reactive Coffee builder DSL ile) - 37 karakter
"#{name}"
ul items.map (i) ->
li i
Nakavt - 100 karakter
<span data-bind="value: name"/>
<ul data-bind="foreach: items">
<li data-bind="value: i"/>
</ul>
Gidon / Bıyık - 66 karakter
{{name}}:
<ul>
{{#items}}
<li>{{.}}</li>
{{/items}}
</ul>
Alt çizgi - 87 karakter
<%- name %>:
<ul>
<% _.each(items, function(i){ %>
<li><%- i %></li>
<% }); %>
</ul>
Mantıksız şablonların vaadi, sanırım, daha geniş beceri setlerine sahip kişilerin, kendilerini ayaklarına vurmadan mantıksız şablonları yönetebilecekleriydi. Bununla birlikte, yukarıdaki örneklerde gördüğünüz şey, dizeye dayalı işaretlemeye minimal mantıksal bir dil eklediğinizde, sonucun daha az değil, daha karmaşık olmasıdır. Ayrıca, eski usul PHP yapıyor gibi görünüyorsunuz.
Açıkça "iş mantığını" (kapsamlı hesaplama) şablonların dışında tutmaya itiraz etmiyorum. Ancak, onlara birinci sınıf bir dil yerine gösterim mantığı için sözde bir dil vererek bedelinin ödendiğini düşünüyorum. Sadece yazmak için daha fazla değil, aynı zamanda birisinin okuması gereken bir bağlam değiştirme karışımı.
Sonuç olarak, mantıksız şablonların mantığını göremiyorum, bu yüzden avantajlarının benim için sıfır olduğunu söyleyebilirim, ancak topluluktaki birçok kişinin bunu farklı görmesine saygı duyuyorum :)
Mantıksız şablon kullanmanın ana avantajları şunlardır:
Brad'e katılıyorum: underscore
tarzın anlaşılması daha kolay. Ama sözdizimsel şekerin herkesi memnun etmeyebileceğini kabul etmeliyim. Eğer _.each
biraz kafa karıştırıcı, geleneksel bir kullanabilirsiniz for
döngü.
<% for(var i = 0; i < items.length; i++) { %>
<%= items[i] %>
<% } %>
for
Veya gibi standart yapılara geri dönebilirseniz her zaman iyidir if
. Sadece kullanmak <% if() %>
veya <% for() %>
ederken Mustache
kullanılması biraz için neologism if-then-else
(ve belgeleri okumak olmasaydı kafa karıştırıcı):
{{#x}}
foo
{{/x}}
{{^x}}
bar
{{/x}}
Şablon motoru, iç içe geçmiş şablonları kolayca elde edebildiğinizde harikadır ( underscore
stil):
<script id="items-tmpl" type="text/template">
<ul>
<% for(var i = 0; i < obj.items.length; i++) { %>
<%= innerTmpl(obj.items[i]) %>
<% } %>
</ul>
</script>
<script id="item-tmpl" type="text/template">
<li>
<%= name %>
</li>
</script>
var tmplFn = function(outerTmpl, innerTmpl) {
return function(obj) {
return outerTmpl({obj: obj, innerTmpl: innerTmpl});
};
};
var tmpl = tmplFn($('#items-tmpl').html(), $('#item-tmpl').html());
var context = { items: [{name:'A',{name:'B'}}] };
tmpl(context);
Temel olarak iç tmpl'nizi bağlamınızın bir özelliği olarak iletirsiniz. Ve buna göre arayın. Tatlı :)
Bu arada, ilgilendiğiniz tek şey şablon motoruysa, bağımsız şablon uygulamasını kullanın. Öyle sadece 900 karakter (4 uzun çizgiler) minified zaman: