สรุป: ตั้งค่าแอ็ตทริบิวต์มุมมองแบบไดนามิกด้วยข้อมูลโมเดล
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() );
}
} );