ข้อดีของเทมเพลตที่ไม่ใช้ลอจิก (เช่นหนวด) คืออะไร?


101

เมื่อเร็ว ๆ นี้ฉันวิ่งเข้าไปหนวดซึ่งจะอ้างว่าเป็นลอจิกน้อยแม่แบบ

อย่างไรก็ตามไม่มีคำอธิบายว่าเหตุใดจึงได้รับการออกแบบในลักษณะที่ไม่ใช้ตรรกะ กล่าวอีกนัยหนึ่งข้อดีของเทมเพลตที่ไม่ใช้ตรรกะคืออะไร?

คำตอบ:


107

กล่าวอีกนัยหนึ่งก็คือป้องกันไม่ให้คุณยิงตัวเองที่เท้า ในสมัยก่อน JSP เป็นเรื่องปกติมากที่จะมีไฟล์ JSP โรยด้วยโค้ด Java ซึ่งทำให้การปรับโครงสร้างใหม่ยากขึ้นเนื่องจากคุณมีโค้ดกระจัดกระจาย

หากคุณป้องกันตรรกะในเทมเพลตโดยการออกแบบ (เช่นเดียวกับที่มีหนวดทำ) คุณจะต้องวางตรรกะไว้ที่อื่นดังนั้นเทมเพลตของคุณจะไม่กระจัดกระจาย

ข้อดีอีกอย่างคือคุณถูกบังคับให้คิดในแง่ของการแยกความกังวล: คอนโทรลเลอร์หรือรหัสลอจิกของคุณจะต้องทำการนวดข้อมูลก่อนที่จะส่งข้อมูลไปยัง UI หากคุณเปลี่ยนเทมเพลตของคุณในภายหลัง (สมมติว่าคุณเริ่มใช้เครื่องมือสร้างเทมเพลตอื่น) การเปลี่ยนจะทำได้ง่ายเพราะคุณต้องใช้รายละเอียด UI เท่านั้น (เนื่องจากไม่มีตรรกะในเทมเพลตโปรดจำไว้)


30
เหตุใดจึงเป็นสิ่งที่ดีที่รหัสคอนโทรลเลอร์จึงมีการนวดข้อมูลในรูปแบบที่จำเป็นในการนำเสนอข้อมูลในลักษณะเฉพาะ เหตุใดจึงเป็นเรื่องดีที่การเปลี่ยนงานนำเสนอมักต้องเปลี่ยนรหัสคอนโทรลเลอร์ ดูเหมือนจะเป็นเรื่องเลวร้ายสำหรับฉัน ฉันคิดว่าเป้าหมายอย่างหนึ่งของภาษาแม่แบบคือการแยกตรรกะของตัวควบคุมออกจากตรรกะการนำเสนอ เทมเพลตใบ้ที่ไม่สามารถตัดสินใจใด ๆ ได้บังคับให้ตรรกะการนำเสนอกลับไปที่โค้ดคอนโทรลเลอร์ ในองค์กรที่บุคคลอื่นทำงานนำเสนอพวกเขาไม่สามารถทำงานด้วยตัวเองได้
jfriend00

8
คุณไม่ควรเตรียมข้อมูลสำหรับมุมมองในคอนโทรลเลอร์ของคุณ Controller ใช้สำหรับควบคุมการไหลของแอปพลิเคชัน สิ่งที่คุณควรทำแทนคือสร้างคลาสผู้นำเสนอที่เปลี่ยนโมเดลของคุณให้เป็นโมเดลมุมมองซึ่งจะถูกใช้โดยมุมมอง โมเดลมุมมองคือแบบจำลองสำหรับ UI ซึ่งแยกจากโมเดลซึ่งเป็นส่วนหนึ่งของตรรกะทางธุรกิจ ขอแนะนำให้คุณชมการ
บรรยาย

1
มันบังคับใช้ตรรกะการนำเสนอบางอย่างไปยังคอนโทรลเลอร์ แต่สิ่งนี้ช่วยให้หลายเลเยอร์การนำเสนอมีหลายแบบ หากคุณต้องการให้ข้อมูลที่คล้ายกันแสดงเป็น JSON, HTML หรือ XML คุณไม่ควรบิดข้อมูล 100% ในเทมเพลต HTML นั่นจะทำให้ JSON และ XML มีตรรกะการแสดงผลบิดของตัวเอง คุณกำลังรวม 80% ของตรรกะการแสดงผลไว้ในคอนโทรลเลอร์และรวมอีก 20% ไว้ในแลมบ์ดาและฟิลเตอร์
chugadie

65

ฉันรู้สึกว่าฉันเกือบจะอยู่คนเดียวในความคิดของฉัน แต่ฉันก็มั่นคงในค่ายตรงข้าม ฉันไม่เชื่อว่าการผสมผสานตรรกะทางธุรกิจที่เป็นไปได้ในเทมเพลตของคุณเป็นเหตุผลเพียงพอที่จะไม่ใช้ภาษาโปรแกรมของคุณอย่างเต็มที่

อาร์กิวเมนต์ตามปกติสำหรับเทมเพลตที่ไม่ใช้ตรรกะคือถ้าคุณสามารถเข้าถึงภาษาโปรแกรมของคุณได้อย่างสมบูรณ์คุณอาจผสมผสานตรรกะที่ไม่มีที่อยู่ในเทมเพลต ฉันพบว่าสิ่งนี้คล้ายกับการให้เหตุผลว่าคุณควรใช้ช้อนหั่นเนื้อเพราะคุณสามารถหั่นเองได้ถ้าคุณใช้มีด นี่เป็นเรื่องจริง แต่คุณจะมีประสิทธิผลมากขึ้นหากคุณใช้อย่างหลังแม้ว่าจะระมัดระวัง

ตัวอย่างเช่นพิจารณาตัวอย่างเทมเพลตต่อไปนี้โดยใช้mustache :

{{name}}:
<ul>
  {{#items}}
    <li>{{.}}</li>
  {{/items}}
</ul>

ฉันเข้าใจสิ่งนี้ แต่ฉันพบว่าสิ่งต่อไปนี้ (โดยใช้ขีดล่าง ) จะง่ายและตรงประเด็นกว่ามาก:

<%- name %>:
<ul>
<% _.each(items, function(i){ %>
  <li><%- i %></li>
<% }); %>
</ul>

ดังที่กล่าวมาฉันเข้าใจว่าเทมเพลตที่ไม่มีตรรกะมีข้อดี (เช่นสามารถใช้กับภาษาโปรแกรมหลายภาษาโดยไม่มีการเปลี่ยนแปลง) ฉันคิดว่าข้อดีอื่น ๆ เหล่านี้สำคัญมาก ฉันไม่คิดว่าธรรมชาติที่ไร้ตรรกะของพวกเขาเป็นหนึ่งในนั้น


135
ฉันแปลกใจที่คุณรู้สึกว่าเทมเพลตขีดล่างเรียบง่ายกว่า .. มันดูไม่ค่อยน่าอ่านสำหรับฉัน แค่ความเห็น :-)
Ben Clayton

9
@ ben-clayton ฉันยอมรับว่าไวยากรณ์แรกสวยกว่าและอาจอ่านได้มากกว่า อย่างไรก็ตามความซับซ้อนที่ฉันขับรถเมื่อฉันพูดว่า "ง่าย"
brad

1
บางครั้งการใช้คำสั่งประกอบก็เหมาะสมในเทมเพลตไม่ว่าคุณจะมีตรรกะใดก็ตาม หรือจะทำอย่างไรถ้าฉันต้องการส่งออกจำนวนรายการในอาร์เรย์? ฉันไม่รู้ว่าฉันจะใช้หนวดได้อย่างไรดูเหมือนว่าจะไม่มีอะไรแบบนั้น
Paul Shapiro

5
@PaulShapiro คุณจะสร้างจำนวนรายการในอาร์เรย์ภายนอกเทมเพลตและเก็บไว้ในตัวแปรแยกต่างหาก
Seun Osewa

4
@brad เทมเพลตขีดล่างเปิดตัวรู XSS nameและitemsอาจมี JavaScript
Matthew

28

หนวดเป็นตรรกะน้อย?

นี่ไม่ใช่เหรอ:

{{#x}}
  foo
{{/x}}
{{^x}}
  bar
{{/x}}

สวยคล้าย ๆ กันนี้?

if x
  "foo"
else
  "bar"
end

และไม่ได้เป็นที่สวยคล้ายกับ (อ่าน: เกือบนิยามของตรรกะ) นำเสนอ?


17
ใช่ถ้าคุณแค่ประเมินความจริงของวัตถุ แต่การพยายามทำอะไรที่ซับซ้อนกว่านั้นไม่สามารถทำได้ ( if x > 0 && x < 10) ... ดังนั้นในขณะที่คุณสามารถใช้ Moustache โดยมีหรือไม่มีตรรกะก็ได้ขึ้นอยู่กับคุณ ท้ายที่สุดมันเป็นเพียงเครื่องมือ
Tom Ashworth

5
คุณกำลังมองหาสิ่งนี้ผิด เพียงเพราะคุณสามารถทำบางสิ่งในภาษาที่ไม่ตรงกับกระบวนทัศน์ทั่วไปไม่ได้หมายความว่าภาษานั้นไม่ได้อยู่ในกระบวนทัศน์นั้น คุณสามารถเขียนโค้ดที่จำเป็นใน Java หรือ Haskell ได้ แต่คุณจะไม่บอกว่านั่นทำให้ Java ไม่ใช่ภาษา OO หรือ Haskell ไม่ใช่ภาษาที่ใช้งานได้ ดูว่าภาษานั้นช่วยให้คุณทำอะไรได้อย่างง่ายดายและสิ่งที่นำคุณไปสู่การดูว่าเป็นภาษาประเภทใด
cjs

@ CurtJ.Samps ในการเปรียบเทียบของคุณจะสมเหตุสมผลถ้า Java ขายตัวเองเป็น "functional-less" หรือถ้า Haskell ขายตัวเองเป็น "object-oriented-less" คำตอบนี้แสดงให้เห็นว่า "ไม่มีตรรกะ" เป็นการเรียกชื่อผิดที่ดีที่สุด
Corey

1
ฉันคิดว่าคุณเห็นด้วยกับฉันที่เมื่อเราเรียกภาษาว่า "functional" เราหมายถึง "มีแนวโน้มที่จะใช้งานได้" ความไม่เห็นด้วยดูเหมือนว่าฉันจะกำหนด "X-less" ว่า "ห่างจาก X" ในขณะที่คุณกำหนดว่า "ไม่สามารถทำ X ได้ทั้งหมด"
cjs

13

เทมเพลตแบบไม่ใช้ตรรกะคือเทมเพลตที่มีช่องว่างให้คุณกรอกไม่ใช่วิธีการเติม ตรรกะถูกวางไว้ที่อื่นและแมปโดยตรงกับเทมเพลต การแยกข้อกังวลนี้เหมาะอย่างยิ่งเพราะเทมเพลตสามารถสร้างขึ้นได้อย่างง่ายดายด้วยตรรกะที่แตกต่างกันหรือแม้กระทั่งกับภาษาโปรแกรมอื่น

จากคู่มือหนวด :

เราเรียกมันว่า "logic-less" เนื่องจากไม่มี if statement, else clauses หรือสำหรับลูป แต่มีเพียงแท็ก แท็กบางแท็กจะถูกแทนที่ด้วยค่าไม่มีอะไรเลยและแท็กอื่น ๆ จะเป็นชุดของค่า เอกสารนี้อธิบายแท็ก Mustache ประเภทต่างๆ


6
คำอธิบายมีความซับซ้อนเล็กน้อยเนื่องจากส่วนต่างๆทำงานค่อนข้างเหมือนเงื่อนไขและการวนซ้ำซึ่งเป็นเพียงส่วนที่ จำกัด มาก ความสามารถในการอ้างถึง callables ในแฮชยังช่วยให้คุณสามารถแปลงส่วนต่างๆเป็นภาษาโปรแกรมพื้นฐานได้ ถึงกระนั้นอย่างน้อยมันก็ทำให้มันแตกต่างที่จะไปตามเส้นทางนั้นแทนที่จะให้กำลังใจ
Tom Anderson

1
แน่นอน แต่ระบบเทมเพลตที่ไม่มีบล็อกสำหรับเงื่อนไขและการทำซ้ำจะค่อนข้างไร้ประโยชน์ ตัวเทมเพลตเองไม่ได้ระบุว่าบล็อกมีไว้เพื่ออะไรหรือจัดการอย่างไร
Jeremy

12

อีกด้านหนึ่งของเหรียญคือในความพยายามอย่างยิ่งยวดที่จะไม่ให้ตรรกะทางธุรกิจหลุดออกจากงานนำเสนอคุณจะต้องใช้ตรรกะในการนำเสนอมากมายในแบบจำลอง ตัวอย่างทั่วไปอาจเป็นไปได้ว่าคุณต้องการใส่คลาส "คี่" และ "คู่" ในแถวที่สลับกันในตารางซึ่งสามารถทำได้โดยใช้ตัวดำเนินการโมดูโลอย่างง่ายในเทมเพลตมุมมอง แต่ถ้าเทมเพลตข้อมูลพร็อพเพอร์ตี้ของคุณไม่อนุญาตให้คุณทำเช่นนั้นในข้อมูลโมเดลของคุณคุณต้องไม่เพียง แต่จัดเก็บว่าแถวใดเป็นเลขคี่หรือคู่ แต่ขึ้นอยู่กับว่าเครื่องมือเทมเพลตของคุณมีข้อ จำกัด เพียงใดคุณอาจต้องทำให้โมเดลของคุณเป็นมลพิษ ด้วยชื่อของคลาส CSS จริง มุมมองควรแยกจากโมเดลแบบเต็มสต็อป แต่โมเดลควรเป็นแบบดูไม่เชื่อเรื่องพระเจ้าและนั่นคือสิ่งที่เอ็นจิ้นเทมเพลต "ไม่ใช้ตรรกะ" เหล่านี้ทำให้คุณลืมไปได้ ตรรกะไปได้ทั้งสองที่ไม่จริงในการตัดสินใจได้อย่างถูกต้องที่จะไป เป็นข้อกังวลในการนำเสนอหรือปัญหาเกี่ยวกับธุรกิจ / ข้อมูลหรือไม่? ด้วยความพยายามที่จะมีมุมมองที่บริสุทธิ์ 100% มลพิษจึงเข้าไปในสถานที่อื่นที่มองเห็นได้น้อยกว่า แต่ไม่เหมาะสมเท่ากัน

มีการเคลื่อนไหวกลับไปในทิศทางอื่นมากขึ้นเรื่อย ๆและหวังว่าสิ่งต่างๆจะรวมศูนย์อยู่ตรงกลางที่สมเหตุสมผลกว่า


6
ต้องไม่เห็นด้วยกับคุณที่นั่น ตรรกะการนำเสนอสำหรับเทมเพลตที่ไม่ใช้ตรรกะจะไม่อยู่ในโมเดล แต่จะอยู่ในมุมมองที่เป็นของ มุมมองรับข้อมูลโมเดลดิบและการนวดเท่าที่จำเป็น (โดยใส่คำอธิบายประกอบแถวคี่ / คู่ ฯลฯ ) เพื่อเตรียมนำเสนอ
acjay

1
เหตุใดมุมมองจึงไม่สามารถเป็นมากกว่าเทมเพลตและรวมโค้ดเพื่อนวดข้อมูลสำหรับเทมเพลตได้
LeeGee

1
acjohnson55 - ฉันเห็นด้วยกับคุณว่าควรไปที่ไหน (ดู) แต่เทมเพลตที่ไม่ใช้ตรรกะช่วยป้องกันสิ่งนั้นได้มาก @LeeGee - ฉันคิดว่ามีฟันเฟืองต่อต้านตรรกะมากเกินไปในมุมมอง แต่สิ่งต่าง ๆ ไปไกลเกินไปในทิศทางอื่นเพื่อป้องกันไม่ให้ตรรกะเฉพาะการนำเสนอในมุมมอง
mattmc3

4
ฉันรู้ว่าฉันไปปาร์ตี้ช้า แต่ควรใช้ CSS ที่ n-item (คี่) เพื่อสลับสีแถว
DanRedux

1
Threre ไม่มีอะไรผิดปกติกับการมีวัตถุการนำเสนอระดับกลางที่สร้างขึ้นโดยมุมมองจากแบบจำลองและคอลเล็กชันหรือข้อมูลอื่น ๆ ด้วยวิธีนี้มุมมองจะสร้างข้อมูลการนำเสนอซึ่งรวมเข้ากับเทมเพลตเพื่อแสดงผลมุมมอง
wprl

11

มันทำให้เทมเพลตของคุณสะอาดขึ้นและบังคับให้คุณเก็บตรรกะไว้ในที่ที่สามารถทดสอบหน่วยได้อย่างเหมาะสม


2
คุณสามารถอธิบายรายละเอียดเพิ่มเติมได้หรือไม่?
Morgan Cheng

29
ใช้เวลาสามเดือนในการทำงานกับระบบโดยใช้ภาษาแม่แบบเชิงตรรกะเช่น JSP กับโปรแกรมเมอร์ที่ไม่กระตือรือร้นในการแยกตรรกะและการนำเสนอ คุณจะพบว่าคุณสร้างระบบที่มีการเขียนโปรแกรมเป็นหลักในหน้า - เลขคณิตสำหรับเค้าโครงตารางเงื่อนไขสำหรับข้อมูลราคาที่จะแสดงและอื่น ๆ ภาษา Templating เป็นภาษาโปรแกรมที่แย่มากดังนั้นจึงเป็นฝันร้ายในการพัฒนาและการบำรุงรักษา บางอย่างเช่น Moustache ไม่ยอมให้คุณเข้าสู่สถานการณ์นั้นตั้งแต่แรก
Tom Anderson

หากลอจิกอยู่ในรูปของฟังก์ชันก็สามารถใช้งานได้โดยระบบไมโครเทมเพลตที่รองรับลอจิกฝังตัวและทดสอบหน่วย ความคิดที่เลวร้ายที่สุดสำหรับฉันดูเหมือนจะเป็น "ตัวช่วย" (โปรดดูspin.atomicobject.com/2011/07/14/… "การใช้งานขั้นสูง") - สิ่งเหล่านี้ดูเหมือนจะเป็นไปไม่ได้ที่จะทดสอบหน่วยเนื่องจากอยู่ในสคริปต์ / พิมพ์ / แท็กข้อความแทนแท็กสคริปต์เก่าธรรมดา (/ type / javascript)
Dexygen

8

บทสนทนานี้ให้ความรู้สึกเหมือนตอนที่พระสงฆ์ในยุคกลางถกเถียงกันว่ามีเทวดากี่องค์ที่สามารถใส่ที่ปลายหมุดได้ กล่าวอีกนัยหนึ่งคือเริ่มรู้สึกว่าศาสนาไร้ประโยชน์และมุ่งเน้นที่ไม่ถูกต้อง

มินิพูดจาโผงผาง (อย่าลังเลที่จะเพิกเฉย):

หากคุณไม่ต้องการอ่านต่อ .. คำตอบสั้น ๆ ของฉันสำหรับหัวข้อข้างต้นคือฉันไม่เห็นด้วยกับเทมเพลตที่ไม่ใช้ตรรกะ ฉันคิดว่ามันเป็นรูปแบบการเขียนโปรแกรมของความคลั่งไคล้ :-) :-)

ตอนนี้การพูดจาโผงผางของฉันยังคงดำเนินต่อไปอย่างเต็มที่: :-)

ฉันคิดว่าเมื่อคุณใช้ความคิดมากมายจนสุดโต่งผลลัพธ์จะกลายเป็นเรื่องน่าหัวเราะ และบางครั้ง (เช่นหัวข้อนี้) ปัญหาก็คือเราใช้ความคิดที่ "ผิด" ไปมาก

การลบตรรกะทั้งหมดออกจากมุมมองเป็น "น่าหัวเราะ" และเป็นความคิดที่ผิด

ย้อนกลับไปสักครู่

คำถามที่เราต้องถามตัวเองคือเอาตรรกะออกทำไม? แนวคิดที่เห็นได้ชัดคือการแยกของความกังวล ให้การประมวลผลมุมมองแยกจากตรรกะทางธุรกิจมากที่สุด ทำไมทำแบบนี้ ช่วยให้เราสามารถสลับมุมมอง (สำหรับแพลตฟอร์มที่แตกต่างกัน: มือถือเบราว์เซอร์เดสก์ท็อป ฯลฯ ) และช่วยให้เราสามารถสลับขั้นตอนการควบคุมลำดับหน้าการเปลี่ยนแปลงการตรวจสอบความถูกต้องการเปลี่ยนแปลงโมเดลการเข้าถึงความปลอดภัยเป็นต้นนอกจากนี้เมื่อตรรกะเป็น ลบออกจากมุมมอง (โดยเฉพาะการดูเว็บ) ทำให้มุมมองอ่านง่ายขึ้นมากและดูแลรักษาได้มากขึ้น ฉันเข้าใจและเห็นด้วยกับสิ่งนั้น

อย่างไรก็ตามการมุ่งเน้นที่การเอาชนะควรอยู่ที่การแยกความกังวล ไม่ใช่มุมมองที่ไม่ใช้ตรรกะ 100% ตรรกะภายในมุมมองควรเกี่ยวข้องกับวิธีการแสดงผล "โมเดล" เท่าที่ฉันกังวลตรรกะในมุมมองนั้นดีมาก คุณสามารถมีตรรกะมุมมองที่ไม่ใช่ตรรกะทางธุรกิจ

ใช่ย้อนกลับไปในวันที่เราเขียนหน้า JSPs, PHP หรือ ASP โดยมีการแยกตรรกะของรหัสและตรรกะการดูเพียงเล็กน้อยหรือไม่มีเลยการบำรุงรักษาเว็บแอปเหล่านี้ถือเป็นฝันร้ายอย่างยิ่ง เชื่อฉันฉันรู้ฉันสร้างและรักษาความชั่วร้ายเหล่านี้ไว้ ในระหว่างขั้นตอนการบำรุงรักษานั้นฉันเข้าใจจริงๆ (โดยอวัยวะภายใน) ข้อผิดพลาดของวิธีการของฉันและเพื่อนร่วมงาน :-) :-)

ดังนั้นคำสั่งจากเบื้องสูง (ผู้เชี่ยวชาญในอุตสาหกรรม) จึงกลายเป็นว่าคุณต้องจัดโครงสร้างเว็บแอปของคุณโดยใช้สิ่งต่างๆเช่นตัวควบคุมมุมมองด้านหน้า (ที่ส่งไปยังตัวจัดการหรือการดำเนินการ [เลือกกรอบงานเว็บของคุณ]) และมุมมองของคุณจะต้องไม่มีรหัส . มุมมองจะกลายเป็นแม่แบบใบ้

ดังนั้นฉันจึงเห็นด้วยโดยทั่วไปกับความเชื่อมั่นข้างต้นไม่ใช่สำหรับรายละเอียดเฉพาะของรายการของคำสั่ง แต่เป็นแรงจูงใจที่อยู่เบื้องหลังคำสั่งซึ่งเป็นความปรารถนาที่จะแยกความกังวลระหว่างมุมมองและตรรกะทางธุรกิจ

ในโครงการหนึ่งที่ฉันมีส่วนร่วมเราพยายามทำตามแนวคิดมุมมองที่ไร้เหตุผลไปจนถึงสุดโต่งที่น่าหัวเราะ เรามีเทมเพลตเอนจินที่สร้างขึ้นเองที่บ้านซึ่งจะช่วยให้เราสามารถสร้างโมเดลอ็อบเจกต์ในรูปแบบ html ได้ มันเป็นระบบที่ใช้โทเค็นง่ายๆ มันแย่มากด้วยเหตุผลง่ายๆเพียงข้อเดียว บางครั้งในมุมมองที่เราต้องตัดสินใจฉันควรแสดงตัวอย่าง HTML เล็กน้อยนี้ .. หรือไม่ .. การตัดสินใจมักจะขึ้นอยู่กับค่าบางอย่างในแบบจำลอง เมื่อคุณไม่มีตรรกะในมุมมองคุณจะทำอย่างไร? คุณทำไม่ได้ ฉันมีข้อโต้แย้งที่สำคัญกับสถาปนิกของเราเกี่ยวกับเรื่องนี้ คนที่ใช้ HTML ส่วนหน้าที่เขียนมุมมองของเรามีปัญหาอย่างสิ้นเชิงเมื่อพวกเขาเผชิญกับสิ่งนี้และเครียดมากเพราะไม่สามารถบรรลุวัตถุประสงค์ง่ายๆ ดังนั้นฉันจึงนำแนวคิดของคำสั่ง IF แบบง่ายๆมาใช้ในเครื่องมือสร้างเทมเพลตของเรา ฉันไม่สามารถบรรยายให้คุณฟังถึงความโล่งใจและความสงบที่เกิดขึ้น ปัญหาได้รับการแก้ไขด้วยแนวคิด IF-Statement ง่ายๆในเทมเพลตของเรา! ทันใดนั้นเครื่องยนต์จำลองของเราก็ดีขึ้น

แล้วเรามาอยู่ในสถานการณ์เครียดโง่ ๆ นี้ได้อย่างไร? เราเน้นผิดวัตถุประสงค์ เราปฏิบัติตามกฎคุณต้องไม่มีตรรกะใด ๆ ในมุมมองของคุณ นั่นเป็นสิ่งที่ผิด ฉันคิดว่า "กฎโดยทั่วไป" ควรจะลดจำนวนตรรกะในมุมมองของคุณให้น้อยที่สุด เพราะถ้าคุณไม่ทำคุณอาจปล่อยให้ตรรกะทางธุรกิจเล็ดลอดเข้ามาในมุมมองโดยไม่ได้ตั้งใจซึ่งจะเป็นการละเมิดการแยกข้อกังวล

ฉันเข้าใจว่าเมื่อคุณประกาศว่า "คุณต้องไม่มีตรรกะในมุมมอง" มันจะกลายเป็นเรื่องง่ายที่จะรู้เมื่อคุณเป็นโปรแกรมเมอร์ที่ "เก่ง" (ถ้านั่นคือการวัดความดีของคุณ). ตอนนี้ลองใช้เว็บแอปที่มีความซับซ้อนปานกลางด้วยกฎข้างต้น มันไม่ง่ายเลย

สำหรับฉันกฎของตรรกะในมุมมองยังไม่ชัดเจนนักและตรงไปตรงมานั่นคือสิ่งที่ฉันต้องการให้เป็น

เมื่อฉันเห็นตรรกะมากมายในมุมมองฉันตรวจพบกลิ่นรหัสและพยายามกำจัดตรรกะส่วนใหญ่ออกจากมุมมอง - ฉันพยายามทำให้แน่ใจว่าตรรกะทางธุรกิจอยู่ที่อื่น - ฉันพยายามแยกข้อกังวล แต่เมื่อฉันเริ่มพูดคุยกับคนที่บอกว่าเราต้องลบตรรกะทั้งหมดออกจากมุมมองสำหรับฉันนั่นเป็นเพียงแค่ความคลั่งไคล้เท่านั้นที่ฉันรู้ว่าคุณสามารถจบลงในสถานการณ์เช่นที่ฉันอธิบายไว้ข้างต้น

ฉันพูดคุยโวเสร็จแล้ว :-)

ไชโย

เดวิด


คำตอบที่ดีคือทุกอย่างเกี่ยวกับแนวทางการเขียนโปรแกรมที่ดี .. และอย่างไรก็ตามการนำเทมเพลตที่ไม่ใช้ตรรกะกลับมาใช้ใหม่ในเซิร์ฟเวอร์และไคลเอนต์จะไม่แห้งเพราะคุณจะต้องทำลอจิกซ้ำในทั้งสองแบบ ..
mateusmaso

5

อาร์กิวเมนต์ที่ดีที่สุดที่ฉันคิดขึ้นสำหรับเทมเพลตแบบไร้ตรรกะคือคุณสามารถใช้เทมเพลตเดียวกันได้ทั้งบนไคลเอนต์และเซิร์ฟเวอร์ อย่างไรก็ตามคุณไม่จำเป็นต้องใช้ตรรกะเพียงภาษาเดียวที่มี "ภาษา" เป็นของตัวเอง ฉันเห็นด้วยกับคนที่บ่นว่าหนวดไม่มีจุดหมาย ขอบคุณ แต่ฉันเป็นเด็กตัวโตและฉันสามารถรักษาเทมเพลตให้สะอาดได้โดยไม่ต้องให้คุณช่วย

อีกทางเลือกหนึ่งคือค้นหาไวยากรณ์เทมเพลตที่ใช้ภาษาที่รองรับทั้งบนไคลเอนต์และเซิร์ฟเวอร์นั่นคือจาวาสคริปต์บนเซิร์ฟเวอร์โดยใช้ node.js หรือคุณสามารถใช้ตัวแปล js และ json ผ่านทางบางอย่างเช่น therubyracer

จากนั้นคุณสามารถใช้สิ่งต่างๆเช่น haml.js ซึ่งสะอาดกว่าตัวอย่างใด ๆ ที่ให้มาและใช้งานได้ดี


ฉันเห็นด้วยอย่างยิ่ง หลังจากอ่านมาสักระยะหนึ่งฉันได้ข้อสรุปว่าความสามารถในการสร้างเทมเพลตใน JS ทั้งฝั่งไคลเอ็นต์และเซิร์ฟเวอร์ตรงกับความต้องการของฉันดีกว่าภาษาเทมเพลตที่เฉพาะเจาะจงจำนวนมาก
christofr

4

ในประโยคเดียว: Logic-less หมายความว่าเครื่องมือเทมเพลตนั้นมีความซับซ้อนน้อยกว่าดังนั้นจึงมีขนาดเล็กลงและมีวิธีการทำงานน้อยกว่าที่ไม่คาดคิด


3

แม้ว่าคำถามจะเก่าและมีคำตอบ แต่ฉันก็อยากจะเพิ่ม 2 ¢ของฉัน (ซึ่งอาจฟังดูพูดจาโผงผาง แต่ก็ไม่ได้เป็นเรื่องของข้อ จำกัด และเมื่อใดที่พวกเขายอมรับไม่ได้)

เป้าหมายของเทมเพลตคือการแสดงผลบางอย่างไม่ใช่เพื่อใช้ตรรกะทางธุรกิจ ตอนนี้มีเส้นบาง ๆ ระหว่างการไม่สามารถทำสิ่งที่คุณต้องทำในเทมเพลตและมี "ตรรกะทางธุรกิจ" อยู่ในนั้น แม้ว่าฉันจะมองโลกในแง่ดีต่อ Moustache และพยายามใช้มัน แต่สุดท้ายก็ไม่สามารถทำสิ่งที่ต้องการได้ในกรณีง่ายๆ

"การนวด" ของข้อมูล (เพื่อใช้คำในคำตอบที่ยอมรับ) อาจกลายเป็นปัญหาที่แท้จริง - ไม่รองรับแม้แต่เส้นทางธรรมดา ๆ (ซึ่งเป็นที่อยู่ Handlebars.js) หากฉันมีข้อมูลดูและจำเป็นต้องปรับแต่งทุกครั้งที่ต้องการแสดงผลบางสิ่งเนื่องจากเครื่องมือแม่แบบของฉันมีข้อ จำกัด มากเกินไปสิ่งนี้จะไม่เป็นประโยชน์ในตอนท้าย และเอาชนะส่วนหนึ่งของความเป็นอิสระของแพลตฟอร์มที่หนวดอ้างว่าเป็นของตัวเอง ฉันต้องทำซ้ำตรรกะการนวดทุกที่

ที่กล่าวว่าหลังจากความไม่พอใจและหลังจากลองใช้เอ็นจิ้นเทมเพลตอื่น ๆ เราก็ได้สร้างของเราเอง (... อีกอัน ... ) ซึ่งใช้ไวยากรณ์ที่ได้รับแรงบันดาลใจจากเทมเพลต. NET Razor มันถูกแยกวิเคราะห์และคอมไพล์บนเซิร์ฟเวอร์และสร้างฟังก์ชัน JS ที่เรียบง่ายและมีอยู่ในตัว (จริงๆแล้วเป็นโมดูล RequireJS) ซึ่งสามารถเรียกใช้เพื่อ "ดำเนินการ" เทมเพลตโดยส่งคืนสตริงเป็นผลลัพธ์ ตัวอย่างที่แบรดมอบให้จะมีลักษณะเช่นนี้เมื่อใช้เอ็นจิ้นของเรา (ซึ่งโดยส่วนตัวแล้วฉันพบว่าดีกว่ามากเมื่อเทียบกับทั้งหนวดและขีดล่าง):

@name:
<ul>
@for (items) {
  <li>@.</li>
}
</ul>

ข้อ จำกัด ที่ปราศจากตรรกะอีกประการหนึ่งส่งผลกระทบต่อเราเมื่อโทรเข้าบางส่วนด้วย Moustache แม้ว่า Moustache จะรองรับบางส่วน แต่ก็ไม่มีความเป็นไปได้ที่จะปรับแต่งข้อมูลที่จะส่งผ่านไปก่อน ดังนั้นแทนที่จะสามารถสร้างเทมเพลตโมดูลาร์และใช้บล็อกเล็ก ๆ ซ้ำได้ฉันจะทำเทมเพลตที่มีโค้ดซ้ำ ๆ อยู่ในนั้นแทน

เราแก้ไขโดยใช้ภาษาแบบสอบถามที่ได้รับแรงบันดาลใจจาก XPath ซึ่งเราเรียกว่า JPath โดยทั่วไปแล้วแทนที่จะใช้ / สำหรับการข้ามไปยังเด็กเราจะใช้จุดและไม่เพียง แต่รองรับสตริงตัวเลขและตัวอักษรบูลีนเท่านั้น แต่ยังรวมถึงอ็อบเจ็กต์และอาร์เรย์ (เช่นเดียวกับ JSON) ภาษานี้ไม่มีผลข้างเคียง (ซึ่งเป็นสิ่งที่จำเป็นสำหรับการทำเทมเพลต) แต่อนุญาตให้ "นวด" ข้อมูลได้ตามต้องการโดยการสร้างวัตถุตัวอักษรใหม่

สมมติว่าเราต้องการแสดงตาราง "ตารางข้อมูล" ที่มีส่วนหัวที่ปรับเปลี่ยนได้และลิงก์ไปยังการดำเนินการในแถวและในภายหลังเพิ่มแถวแบบไดนามิกโดยใช้ jQuery ดังนั้นแถวจึงต้องอยู่ในบางส่วนหากฉันไม่ต้องการทำโค้ดซ้ำ และนั่นคือจุดเริ่มต้นของปัญหาหากข้อมูลเพิ่มเติมบางอย่างเช่นคอลัมน์ใดที่จะแสดงผลเป็นส่วนหนึ่งของโมเดลมุมมองและเหมือนกันสำหรับการกระทำเหล่านั้นในแต่ละแถว นี่คือโค้ดที่ใช้งานได้จริงโดยใช้เทมเพลตและเครื่องมือค้นหาของเรา:

เทมเพลตตาราง:

<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>

เทมเพลตแถว:

<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:

var html = table({
    columns: [
        { title: "Username", property: "username" },
        { title: "E-Mail", property: "email" }
    ],
    actions: [
        { id: "delete", name: "Delete" }
    ],
    rows: GetAjaxRows()
})

ไม่มีตรรกะทางธุรกิจใด ๆ ในนั้น แต่สามารถใช้ซ้ำได้และกำหนดค่าได้และยังไม่มีผลข้างเคียง


13
ฉันไม่เห็นประเด็นของคำตอบนี้โดยสุจริตมันไม่ได้ตอบคำถามเลย คุณพูดว่ามีข้อ จำกัด โดยไม่ต้องอธิบายว่ามันคืออะไรหรือเกิดขึ้นได้อย่างไร ในที่สุดคุณก็เริ่มเข้าสู่การอภิปรายเกี่ยวกับระบบของคุณเองซึ่งไม่มีให้ใครเห็นในความเป็นจริงมันอาจจะดูดและอาจจบลงในวันหนึ่งใน thedailywtf แต่เราไม่เคยรู้ เปิดแหล่งที่มาเชื่อมโยงและให้เราตัดสินใจ!
mattmanser

1
@mattmanser ฉันเขียนเกี่ยวกับข้อ จำกัด ที่ทำให้ไม่ใช้ Mustache (และ Handlebars): ขาดการสนับสนุนเส้นทางเพรดิเคตตัวแปรการแปลงข้อมูลสำหรับการเรียกใช้บางส่วน สิ่งเหล่านี้ล้วนสำคัญสำหรับเรา เราอาจจะโอเพ่นซอร์สโค้ดในบางวัน แต่เนื่องจากเป็นโซลูชันฝั่งเซิร์ฟเวอร์ (หรือเวลาคอมไพล์หากคุณต้องการ) ซึ่งรวบรวมเทมเพลตเข้ากับโค้ด JS จึงไม่มีผู้ชมจำนวนมากเช่นเดียวกับ Mustache หากคุณต้องการติดต่อโปรดอย่าลังเลที่จะติดต่อฉัน - ฉันยังเป็นผู้เขียน bsn GoldParser ด้วยรหัส Google (ซึ่งคุณสามารถค้นหาอีเมลของฉันได้อย่างง่ายดายในไฟล์ readme)
Lucero

ฉันชอบความคิดของมีดโกนของคุณเหมือนเครื่องยนต์ ... มันเป็นโอเพ่นซอร์สหรือไม่?
ข้าวเกรียบ

@Cracker ไม่ยังไม่ (ยัง) - "ปัญหา" คือขณะนี้เทมเพลตถูกคอมไพล์เป็นรหัส JS บนเซิร์ฟเวอร์ที่ใช้ ASP.NET MVC ดังนั้นกลุ่มเป้าหมายจึงไม่ใหญ่เท่ากับเครื่องมือสร้างเทมเพลตอื่น ๆ . นอกจากนั้นยังเป็นส่วนหนึ่งของไลบรารีที่ใหญ่กว่าที่เราต้องแยกออกจากกันเพื่อเปิดแหล่งที่มา
Lucero

1
@Esailija อนุญาตให้ระบุชื่อคุณสมบัติแบบไดนามิกที่จะนำมาจากrowอ็อบเจ็กต์แทนที่จะใช้ชื่อแบบคงที่ เช่นถ้า$col.property == 'Something'สิ่งนี้จะให้เนื้อหาของrow.Something.
Lucero

2

มี 3 วิธีในการแสดงรายการโดยมีการนับอักขระ ทั้งหมดยกเว้นภาษาแรกและสั้นที่สุดอยู่ในภาษาแม่แบบที่ไม่ใช้ตรรกะ ..

CoffeeScript (พร้อมDSL ตัวสร้างกาแฟปฏิกิริยา ) - 37 ตัวอักษร

"#{name}"
ul items.map (i) ->
  li i

สิ่งที่น่าพิศวง - 100 ตัวอักษร

<span data-bind="value: name"/>
<ul data-bind="foreach: items">
   <li data-bind="value: i"/>
</ul>

แฮนด์ / หนวด - 66 ตัว

{{name}}:
<ul>
  {{#items}}
    <li>{{.}}</li>
  {{/items}}
</ul>

ขีดล่าง - 87 ตัวอักษร

<%- name %>:
<ul>
<% _.each(items, function(i){ %>
  <li><%- i %></li>
<% }); %>
</ul>

ฉันคิดว่าสัญญาของเทมเพลตที่ไม่ใช้ตรรกะคือฉันคิดว่าผู้ที่มีชุดทักษะที่กว้างขึ้นจะสามารถจัดการเทมเพลตที่ไม่ใช้ตรรกะได้โดยไม่ต้องถ่ายภาพตัวเอง อย่างไรก็ตามสิ่งที่คุณเห็นในตัวอย่างข้างต้นคือเมื่อคุณเพิ่มภาษาลอจิกขั้นต่ำในมาร์กอัปแบบสตริงผลลัพธ์จะซับซ้อนกว่าไม่ใช่น้อย นอกจากนี้คุณดูเหมือนว่าคุณกำลังทำ PHP แบบเก่า

เห็นได้ชัดว่าฉันไม่คัดค้านที่จะรักษา "ตรรกะทางธุรกิจ" (การคำนวณแบบครอบคลุม) จากเทมเพลต แต่ฉันคิดว่าการให้ภาษาหลอกสำหรับตรรกะในการแสดงผลแทนภาษาชั้นหนึ่งจะเป็นการจ่ายราคา ไม่เพียงแค่พิมพ์มากขึ้นเท่านั้น แต่ยังเป็นการผสมผสานที่น่ากลัวของการสลับบริบทที่ใครบางคนต้องอ่าน

สรุปได้ว่าฉันไม่เห็นตรรกะของเทมเพลตที่ไม่ใช้ตรรกะดังนั้นฉันจะบอกว่าข้อได้เปรียบของพวกเขานั้นไม่มีประโยชน์สำหรับฉัน แต่ฉันเคารพที่หลายคนในชุมชนเห็นว่ามันแตกต่างออกไป :)


@brad คุณคิดอย่างไรกับการเปรียบเทียบนี้?
Dean Radcliffe

2

ข้อดีหลักของการใช้เทมเพลตที่ไม่ใช้ตรรกะคือ:

  • บังคับใช้การแยกมุมมองแบบจำลองอย่างเคร่งครัดโปรดดูรายละเอียดในเอกสารนี้ (แนะนำเป็นอย่างยิ่ง)
  • มากง่ายต่อการเข้าใจและการใช้งานเพราะไม่มีตรรกะการเขียนโปรแกรม (และความรู้!) เป็นสิ่งจำเป็นและไวยากรณ์มีน้อย
  • (หนวดโดยเฉพาะ) พกพาได้สูงและเป็นอิสระจากภาษาสามารถใช้งานได้โดยไม่ต้องดัดแปลงในสภาพแวดล้อมการเขียนโปรแกรมเกือบทั้งหมด

คำตอบที่กระชับ!
MrWatson

1

ฉันเห็นด้วยกับแบรด: underscoreรูปแบบนี้เข้าใจง่ายกว่า แต่ฉันต้องยอมรับว่าน้ำตาลที่เป็นประโยคอาจไม่ถูกใจทุกคน หาก_.eachค่อนข้างสับสนคุณสามารถใช้forลูปแบบเดิมได้

  <% for(var i = 0; i < items.length; i++) { %>
    <%= items[i] %>
  <% } %>

มันก็มักจะมีความสุขถ้าคุณสามารถ fallback เพื่อสร้างมาตรฐานเช่นหรือfor ifเพียงใช้<% if() %>หรือ<% for() %>ในขณะที่Mustacheใช้ neologism สำหรับif-then-else(และสับสนหากคุณไม่ได้อ่านเอกสารประกอบ):

{{#x}}
  foo
{{/x}}
{{^x}}
  bar
{{/x}}

เครื่องมือเทมเพลตนั้นยอดเยี่ยมเมื่อคุณสามารถสร้างเทมเพลตที่ซ้อนกันได้อย่างง่ายดาย ( underscoreสไตล์):

<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);

โดยทั่วไปคุณส่ง tmpl ภายในของคุณเป็นคุณสมบัติของบริบทของคุณ และเรียกตามนั้น. หวาน :)

อย่างไรก็ตามหากสิ่งเดียวที่คุณสนใจคือเครื่องมือเทมเพลตให้ใช้การใช้งานเทมเพลตแบบสแตนด์อโลน มันเป็นเพียง 900 ตัวอักษรเมื่อ minified (4 เส้นยาว):

https://gist.github.com/marlun78/2701678

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.