ฉันได้อ่านล็อตที่ Backbone ไม่ได้ผูกมัดสองทาง แต่ฉันไม่เข้าใจแนวคิดนี้อย่างแน่นอน
ใครบางคนสามารถให้ฉันตัวอย่างของวิธีการผูกสองวิธีทำงานในรหัสฐาน MVC และวิธีที่ไม่ได้กับ Backbone?
ฉันได้อ่านล็อตที่ Backbone ไม่ได้ผูกมัดสองทาง แต่ฉันไม่เข้าใจแนวคิดนี้อย่างแน่นอน
ใครบางคนสามารถให้ฉันตัวอย่างของวิธีการผูกสองวิธีทำงานในรหัสฐาน MVC และวิธีที่ไม่ได้กับ Backbone?
คำตอบ:
การผูกสองทางหมายถึง:
Backbone ไม่มีการนำ "baked-in" ไปใช้ # 2 (แม้ว่าคุณจะสามารถทำได้โดยใช้ Event listeners) กรอบอื่น ๆเช่นสิ่งที่น่าพิศวงไม่ลวดขึ้นสองทางผูกพันโดยอัตโนมัติ
ใน Backbone คุณสามารถบรรลุ # 1 ได้อย่างง่ายดายโดยผูกเมธอด "render" ของมุมมองกับเหตุการณ์ "เปลี่ยน" ของโมเดล เพื่อให้บรรลุ # 2 คุณจะต้องเพิ่มฟังการเปลี่ยนแปลงไปยังองค์ประกอบอินพุตและโทรmodel.set
ในตัวจัดการ
นี่คือซอที่มีการเชื่อมโยงสองทางใน Backbone
สองทางผูกพันหมายถึงว่ามีการเปลี่ยนแปลงข้อมูลที่เกี่ยวข้องกับผลกระทบต่อรูปแบบที่มีการแพร่กระจายทันทีไปยังมุมมองที่ตรงกัน (s), และว่าการเปลี่ยนแปลงใด ๆ ที่ทำในมุมมอง (s) (พูดโดยผู้ใช้) จะมีผลทันทีในรูปแบบพื้นฐาน . เมื่อข้อมูลแอปมีการเปลี่ยนแปลง UI จะทำเช่นนั้นและตรงกันข้าม
นี่เป็นแนวคิดที่มั่นคงมากในการสร้างแอปพลิเคชันบนเว็บเพราะจะทำให้ "รุ่น" นามธรรมเป็นแหล่งข้อมูลอะตอมที่ปลอดภัยและใช้งานได้ทุกที่ภายในแอปพลิเคชัน ถ้ารูปแบบนั้นถูกผูกไว้กับมุมมองการเปลี่ยนแปลงชิ้นส่วนที่ตรงกันของ UI (มุมมอง) จะสะท้อนสิ่งนั้นไม่ว่าจะเกิดอะไรขึ้น และชิ้นส่วนที่ตรงกันของ UI (มุมมอง) สามารถใช้เป็นเครื่องมือในการรวบรวมอินพุต / ข้อมูลของผู้ใช้อย่างปลอดภัยเพื่อรักษาข้อมูลแอปพลิเคชันที่ทันสมัย
การใช้การเชื่อมโยงแบบสองทางที่ดีควรทำให้การเชื่อมต่อระหว่างโมเดลและมุมมองบางอย่างง่ายที่สุดเท่าที่จะทำได้จากมุมมองของนักพัฒนาซอฟต์แวร์
ดังนั้นจึงเป็นเรื่องไม่จริงที่จะบอกว่า Backbone ไม่รองรับการเชื่อมต่อแบบสองทาง: แม้ว่าจะไม่ใช่คุณสมบัติหลักของเฟรมเวิร์ก แต่ก็สามารถทำได้โดยใช้กิจกรรมของ Backbone มันมีค่าใช้จ่ายสองสามบรรทัดของรหัสที่ชัดเจนสำหรับกรณีง่าย ๆ ; และอาจกลายเป็นอันตรายสำหรับการผูกที่ซับซ้อนมากขึ้น นี่เป็นกรณีง่าย ๆ (โค้ดที่ยังไม่ทดลองซึ่งเขียนขึ้นมาเพื่อการแสดงภาพประกอบ):
Model = Backbone.Model.extend
defaults:
data: ''
View = Backbone.View.extend
template: _.template("Edit the data: <input type='text' value='<%= data %>' />")
events:
# Listen for user inputs, and edit the model.
'change input': @setData
initialize: (options) ->
# Listen for model's edition, and trigger UI update
@listenTo @model, 'change:data', @render
render: ->
@$el.html @template(@model.attributes)
@
setData: (e) =>
e.preventDefault()
@model.set 'data', $(e.currentTarget).value()
model: new Model()
view = new View {el: $('.someEl'), model: model}
นี่เป็นรูปแบบที่ค่อนข้างธรรมดาในแอปพลิเคชั่น Backbone แบบดิบ อย่างที่เราเห็นมันต้องใช้โค้ด (มาตรฐานที่ค่อนข้างดี) ในปริมาณที่เหมาะสม
AngularJSและทางเลือกอื่น ๆ ( Ember , สิ่งที่น่าพิศวง …) ให้การผูกมัดแบบสองทางในฐานะพลเมืองคนแรก พวกเขาสรุปกรณีขอบจำนวนมากภายใต้ DSL บางตัวและทำอย่างดีที่สุดในการบูรณาการการเชื่อมโยงสองทางในระบบนิเวศ ตัวอย่างของเราจะมีลักษณะเช่นนี้กับ AngularJS (รหัสที่ยังไม่ทดลองดูด้านบน):
<div ng-app="app" ng-controller="MainCtrl">
Edit the data:
<input name="mymodel.data" ng-model="mymodel.data">
</div>
angular.module('app', [])
.controller 'MainCtrl', ($scope) ->
$scope.mymodel = {data: ''}
ค่อนข้างสั้น!
แต่ทราบว่าบางเต็มเปี่ยมสองทางส่วนขยายที่มีผลผูกพันทำอยู่สำหรับหัวใจเช่นกัน (ในดิบเพื่อทัศนะของการลดความซับซ้อน): อีพ็อกซี่ , Stickit , ModelBinder ...
ยกตัวอย่างเช่นสิ่งที่ยอดเยี่ยมอย่างหนึ่งกับ Epoxy คือมันช่วยให้คุณสามารถประกาศการโยงของคุณ (แอตทริบิวต์ DOM <-> องค์ประกอบของมุมมองโมเดล) ทั้งในเทมเพลต (DOM) หรือภายในการนำมุมมองไปใช้ (JavaScript) บางคนไม่ชอบการเพิ่ม "directives" ลงใน DOM / เท็มเพลต (เช่นแอตทริบิวต์ ng- * ที่ AngularJS ต้องการหรือแอตทริบิวต์ data-bind ของ Ember)
ยกตัวอย่างจาก Epoxy เราสามารถนำแอปพลิเคชั่น Backbone ดิบกลับมาใช้ใหม่ในลักษณะนี้ (…):
Model = Backbone.Model.extend
defaults:
data: ''
View = Backbone.Epoxy.View.extend
template: _.template("Edit the data: <input type='text' />")
# or, using the inline form: <input type='text' data-bind='value:data' />
bindings:
'input': 'value:data'
render: ->
@$el.html @template(@model.attributes)
@
model: new Model()
view = new View {el: $('.someEl'), model: model}
สรุปกรอบ JS หลัก "หลัก" ทั้งหมดสนับสนุนการเชื่อมโยงสองทาง บางคนเช่น Backbone จำเป็นต้องมีงานพิเศษบางอย่างเพื่อให้ทำงานได้อย่างราบรื่นแต่งานเหล่านั้นเหมือนกันซึ่งไม่บังคับใช้วิธีเฉพาะในการเริ่มต้น ดังนั้นมันจึงเป็นเรื่องของสภาพจิตใจของคุณ
นอกจากนี้คุณอาจสนใจFluxซึ่งเป็นสถาปัตยกรรมที่แตกต่างกันสำหรับเว็บแอปพลิเคชันที่ส่งเสริมการเชื่อมโยงทางเดียวผ่านรูปแบบวงกลม มันขึ้นอยู่กับแนวคิดของการเรนเดอร์การแสดงผลส่วนประกอบของ UI ที่รวดเร็วและเป็นองค์รวมอย่างรวดเร็วเมื่อมีการเปลี่ยนแปลงข้อมูลใด ๆ เพื่อให้แน่ใจว่ามีการเชื่อมโยงกัน ในแนวโน้มเดียวกันคุณอาจต้องการตรวจสอบแนวคิดของ MVI (Model-View-เจตนา) ตัวอย่างเช่นวงจร
McGarnagle มีคำตอบที่ยอดเยี่ยมและคุณจะต้องยอมรับเขา แต่ฉันคิดว่าฉันจะพูดถึง (ตั้งแต่คุณถาม) วิธีการทำงานของฐานข้อมูล
โดยทั่วไปแล้วจะนำไปใช้โดยการยิงเหตุการณ์เมื่อใดก็ตามที่มีการเปลี่ยนแปลงข้อมูลซึ่งจะทำให้ผู้ฟัง (เช่น UI) ได้รับการอัปเดต
การเชื่อมโยงแบบสองทางทำงานโดยการทำสองครั้งด้วยความระมัดระวังเล็กน้อยเพื่อให้แน่ใจว่าคุณจะไม่ติดขัดในลูปเหตุการณ์ (ที่การอัปเดตจากเหตุการณ์ทำให้เกิดเหตุการณ์อื่นที่จะถูกไล่ออก)
ฉันจะใส่ความคิดเห็นนี้ แต่มันก็ค่อนข้างยาว ...
ที่จริงemberjs
สนับสนุนสองทางที่มีผลผูกพันซึ่งเป็นหนึ่งในคุณลักษณะที่มีประสิทธิภาพมากที่สุดสำหรับจาวาสคริปต์กรอบ MVC คุณสามารถตรวจสอบว่ามันพูดถึงbinding
ในคู่มือผู้ใช้
สำหรับ emberjs การสร้างการผูกสองทางคือการสร้างคุณสมบัติใหม่ด้วยการผูกสตริงที่ส่วนท้ายจากนั้นระบุพา ธ จากขอบเขตโกลบอล:
App.wife = Ember.Object.create({
householdIncome: 80000
});
App.husband = Ember.Object.create({
householdIncomeBinding: 'App.wife.householdIncome'
});
App.husband.get('householdIncome'); // 80000
// Someone gets raise.
App.husband.set('householdIncome', 90000);
App.wife.get('householdIncome'); // 90000
โปรดทราบว่าการเชื่อมโยงจะไม่อัปเดตทันที Ember รอจนกว่ารหัสแอปพลิเคชันทั้งหมดของคุณจะทำงานเสร็จสิ้นก่อนที่จะซิงโครไนซ์การเปลี่ยนแปลงดังนั้นคุณสามารถเปลี่ยนคุณสมบัติที่ถูกผูกไว้ได้หลายครั้งตามที่คุณต้องการโดยไม่ต้องกังวลเกี่ยวกับค่าใช้จ่ายในการซิงค์
หวังว่าจะช่วยในการขยายคำตอบที่เลือกเดิม
เป็นมูลค่าการกล่าวขวัญว่ามีวิธีแก้ไขปัญหาต่าง ๆ มากมายซึ่งเสนอสองทางผูกพันและเล่นจริง ๆ ทาง
ผมมีประสบการณ์ที่น่าพอใจกับรูปแบบเครื่องผูกนี้ - https://github.com/theironcook/Backbone.ModelBinder ซึ่งให้ค่าเริ่มต้นที่สมเหตุสมผลยังมีการแม็พ jquery selector แบบกำหนดเองของคุณลักษณะของโมเดลกับองค์ประกอบอินพุต
มีรายการเพิ่มเติมของส่วนขยาย / ปลั๊กอินของกระดูกสันหลังบนgithub