สรุป: ตั้งค่าแอ็ตทริบิวต์มุมมองแบบไดนามิกด้วยข้อมูลโมเดล
http://jsfiddle.net/5wd0ma8b/
var View = Backbone.View.extend( {
attributes : function () {
return {
class : this.model.get( 'item_class' ),
id : this.model.get( 'item_id' )
};
}
} );
var item = new View( {
model : new Backbone.Model( {
item_class : "nice",
item_id : "id1"
} )
} );
ตัวอย่างนี้สมมติว่าคุณอนุญาตให้ Backbone สร้างองค์ประกอบ DOM ให้คุณ
attributesวิธีการที่เรียกว่าหลังจากคุณสมบัติส่งผ่านไปยังตัวสร้างมุมมองที่มีการตั้งค่า (ในกรณีนี้model) elที่ช่วยให้คุณสามารถตั้งค่าแบบไดนามิกคุณลักษณะที่มีข้อมูลรูปแบบก่อนที่จะสร้างโครง
ตรงกันข้ามกับคำตอบอื่น ๆ : ไม่ใช้ค่าแอตทริบิวต์ฮาร์ดโค้ดในคลาสมุมมองตั้งค่าแบบไดนามิกจากข้อมูลโมเดล ไม่รอจนกว่าrender()จะตั้งค่า attr vals; ไม่ได้ตั้งค่าซ้ำ ๆ attr Vals ในการเรียกร้องให้ทุกคนrender(); ไม่ได้ตั้งค่า attr vals บนองค์ประกอบ DOM ด้วยตนเองโดยไม่จำเป็น
โปรดทราบว่าหากตั้งค่าคลาสเมื่อเรียกBackbone.View.extendหรือตัวสร้างมุมมอง (เช่นnew Backbone.View) คุณต้องใช้ชื่อคุณสมบัติ DOM classNameแต่ถ้าตั้งค่าผ่านattributesแฮช / วิธีการ (ดังตัวอย่างนี้) คุณต้องใช้ชื่อแอตทริบิวต์, class.
ณ Backbone 0.9.9:
เมื่อประกาศ View ... el, tagName, idและclassNameตอนนี้อาจจะกำหนดเป็นฟังก์ชั่นถ้าคุณต้องการค่าของพวกเขาที่จะได้รับการพิจารณาที่รันไทม์
ฉันพูดถึงเรื่องนี้ในกรณีที่มีสถานการณ์ที่จะเป็นประโยชน์เป็นทางเลือกในการใช้attributesวิธีการตามภาพประกอบ
ใช้องค์ประกอบที่มีอยู่
หากคุณใช้องค์ประกอบที่มีอยู่ (เช่นส่งผ่านelไปยังตัวสร้างมุมมอง) ...
var item = new View( { el : some_el } );
... จากนั้นattributesจะไม่ถูกนำไปใช้กับองค์ประกอบ หากคุณลักษณะที่ต้องการไม่ได้ตั้งอยู่บนองค์ประกอบหรือคุณไม่ต้องการที่จะทำซ้ำข้อมูลนั้นในระดับมุมมองของคุณและสถานที่อื่นแล้วคุณอาจต้องการที่จะเพิ่มinitializeวิธีการเพื่อให้ตัวสร้างมุมมองของคุณที่ใช้ในการattributes elสิ่งนี้ (ใช้jQuery.attr):
View.prototype.initialize = function ( options ) {
this.$el.attr( _.result( this, 'attributes' ) );
};
การใช้งานการelแสดงผลการหลีกเลี่ยงกระดาษห่อหุ้ม
ในตัวอย่างส่วนใหญ่ที่ฉันได้เห็น el ของมุมมองทำหน้าที่เป็นองค์ประกอบของ wrapper ที่ไม่มีความหมายซึ่งต้องเขียนโค้ด 'ความหมาย' ด้วยตนเอง
ไม่มีเหตุผลที่view.elจะต้องเป็น "องค์ประกอบเสื้อคลุมที่ไร้ความหมาย" ในความเป็นจริงสิ่งนี้มักจะทำลายโครงสร้าง DOM หากคลาสมุมมองเป็นตัวแทนของ<li>องค์ประกอบตัวอย่างเช่นจำเป็นต้องแสดงผลเป็น<li>- การแสดงผลเป็น<div>องค์ประกอบหรือองค์ประกอบอื่นใดจะทำให้โมเดลเนื้อหาเสียหาย คุณอาจจะต้องการที่จะมุ่งเน้นไปที่การตั้งค่าได้อย่างถูกต้ององค์ประกอบมุมมองของคุณ (โดยใช้คุณสมบัติเช่นtagName, classNameและid) และจากนั้นการแสดงผลของเนื้อหานั้นไม่นาน
ตัวเลือกสำหรับวิธีทำให้วัตถุมุมมอง Backbone ของคุณโต้ตอบกับ DOM นั้นเปิดกว้าง สถานการณ์เริ่มต้นพื้นฐานมี 2 สถานการณ์:
มีหลายวิธีที่คุณสามารถสร้างเนื้อหาสำหรับองค์ประกอบได้ (ตั้งค่าสตริงตามตัวอักษรตามตัวอย่างของคุณใช้ไลบรารีเทมเพลตเช่นหนวดแฮนด์บาร์ ฯลฯ ) คุณควรใช้ไฟล์elคุณสมบัติของมุมมองอย่างไรขึ้นอยู่กับสิ่งที่คุณทำ
องค์ประกอบที่มีอยู่
ตัวอย่างการแสดงผลของคุณแสดงให้เห็นว่าคุณมีองค์ประกอบที่คุณกำหนดให้กับมุมมองอยู่แล้วแม้ว่าคุณจะไม่แสดงการสร้างอินสแตนซ์ของมุมมองก็ตาม หากเป็นกรณีนี้และองค์ประกอบนั้นอยู่ในเอกสารแล้วคุณอาจต้องการทำสิ่งนี้ (อัปเดตเนื้อหาelแต่อย่าแก้ไขelเอง):
render : function () {
this.$el.html( "Some stuff" );
}
http://jsfiddle.net/vQMa2/1/
องค์ประกอบที่สร้างขึ้น
สมมติว่าคุณไม่มีองค์ประกอบที่มีอยู่และคุณอนุญาตให้ Backbone สร้างขึ้นมาให้คุณ คุณอาจต้องการทำบางสิ่งเช่นนี้ (แต่น่าจะดีกว่าที่จะออกแบบสิ่งต่าง ๆ เพื่อให้มุมมองของคุณไม่รับผิดชอบต่อการรับรู้สิ่งที่อยู่ภายนอกตัวมันเอง):
render : function () {
this.$el.html( "Some stuff" );
$( "#some-container" ).append( this.el );
}
http://jsfiddle.net/vQMa2/
เทมเพลต
ในกรณีของฉันฉันกำลังใช้เทมเพลตเช่น:
<div class="player" id="{{id}}">
<input name="name" value="{{name}}" />
<input name="score" value="{{score}}" />
</div>
<!-- .player -->
เทมเพลตแสดงถึงมุมมองที่สมบูรณ์ กล่าวอีกนัยหนึ่งคือจะไม่มีกระดาษห่อหุ้มรอบเทมเพลต -div.playerจะเป็นองค์ประกอบรูทหรือองค์ประกอบนอกสุดของมุมมองของฉัน
คลาสผู้เล่นของฉันจะมีลักษณะดังนี้ (พร้อมตัวอย่างที่เรียบง่ายมากrender()):
Backbone.View.extend( {
tagName : 'div',
className : 'player',
attributes : function () {
return {
id : "player-" + this.model.cid
};
},
render : function {
var rendered_template = $( ... );
this.$el.empty().append( rendered_template.children() );
}
} );