Đâ là một câu hỏi tuyệt vời. Xương sống là tuyệt vời vì thiếu các giả định mà nó đưa ra, nhưng nó có nghĩa là bạn phải (quyết định làm thế nào) tự thực hiện những điều như thế này. Sau khi xem qua nội dung của riêng tôi, tôi thấy rằng tôi (loại) sử dụng kết hợp kịch bản 1 và kịch bản 2. Tôi không nghĩ kịch bản ma thuật thứ 4 tồn tại bởi vì, đơn giản, mọi thứ bạn làm trong kịch bản 1 & 2 phải là làm xong.
Tôi nghĩ rằng sẽ dễ dàng nhất để giải thích cách tôi muốn xử lý nó bằng một ví dụ. Nói rằng tôi có trang đơn giản này được chia thành các chế độ xem được chỉ định:
Giả sử HTML là, sau khi được hiển thị, một cái gì đó như thế này:
<div id="parent">
<div id="name">Person: Kevin Peel</div>
<div id="info">
First name: <span class="first_name">Kevin</span><br />
Last name: <span class="last_name">Peel</span><br />
</div>
<div>Phone Numbers:</div>
<div id="phone_numbers">
<div>#1: 123-456-7890</div>
<div>#2: 456-789-0123</div>
</div>
</div>
Hy vọng rằng HTML khá phù hợp với sơ đồ.
Các ParentView
tổ chức 2 lần xem đứa trẻ,InfoView
và PhoneListView
cũng như một vài div bổ sung, một trong số đó #name
, cần được đặt ở một số điểm. PhoneListView
giữ quan điểm con của riêng nó, một loạt các PhoneView
mục.
Vì vậy, câu hỏi thực tế của bạn. Tôi xử lý khởi tạo và kết xuất khác nhau dựa trên kiểu xem. Tôi chia quan điểm của tôi thành hai loại, Parent
quan điểm và Child
quan điểm.
Sự khác biệt giữa chúng là đơn giản, các Parent
khung nhìn giữ các khung nhìn con trong khi các Child
khung nhìn thì không. Vì vậy, trong ví dụ của tôi, ParentView
và PhoneListView
là các Parent
khung nhìn, trong khiInfoView
và các PhoneView
mục là các Child
khung nhìn.
Giống như tôi đã đề cập trước đây, sự khác biệt lớn nhất giữa hai loại này là khi chúng được phép kết xuất. Trong một thế giới hoàn hảo, tôi muốnParent
khung nhìn chỉ hiển thị một lần. Tùy thuộc vào chế độ xem con của họ để xử lý bất kỳ kết xuất lại nào khi (các) mô hình thay đổi. Child
mặt khác, tôi cho phép hiển thị lại bất cứ lúc nào họ cần vì họ không có bất kỳ quan điểm nào khác dựa vào họ.
Chi tiết hơn một chút, để Parent
xem tôi thíchinitialize
chức năng thực hiện một số điều:
- Khởi tạo quan điểm của riêng tôi
- Kết xuất quan điểm của riêng tôi
- Tạo và khởi tạo bất kỳ khung nhìn con.
- Chỉ định mỗi đứa trẻ xem một yếu tố trong chế độ xem của tôi (ví dụ:
InfoView
sẽ được chỉ định #info
).
Bước 1 là khá tự giải thích.
Bước 2, kết xuất, được thực hiện sao cho mọi phần tử mà khung nhìn con dựa vào đã tồn tại trước khi tôi cố gắng gán chúng. Bằng cách này, tôi biết tất cả trẻ em events
sẽ được đặt chính xác và tôi có thể kết xuất lại các khối của chúng nhiều lần như tôi muốn mà không phải lo lắng về việc phải ủy quyền lại bất cứ điều gì. Tôi thực sự không render
có bất kỳ quan điểm trẻ em nào ở đây, tôi cho phép chúng làm điều đó trong chính chúnginitialization
.
Bước 3 và 4 thực sự được xử lý cùng lúc khi tôi vượt qua el
trong khi tạo chế độ xem con. Tôi muốn thông qua một yếu tố ở đây vì tôi cảm thấy phụ huynh nên xác định nơi nào trong quan điểm riêng của mình, đứa trẻ được phép đặt nội dung của nó.
Để kết xuất, tôi cố gắng giữ nó khá đơn giản để Parent
xem. Tôi muốn render
chức năng không làm gì hơn là hiển thị khung nhìn cha. Không có phái đoàn sự kiện, không hiển thị quan điểm trẻ em, không có gì. Chỉ là một kết xuất đơn giản.
Đôi khi điều này không phải lúc nào cũng làm việc. Ví dụ trong ví dụ của tôi ở trên, #name
phần tử sẽ cần được cập nhật bất cứ khi nào tên trong mô hình thay đổi. Tuy nhiên, khối này là một phần của ParentView
mẫu và không được xử lý bởi Child
chế độ xem chuyên dụng , vì vậy tôi làm việc xung quanh đó. Tôi sẽ tạo ra một số loại subRender
chức năng chỉ thay thế nội dung của #name
phần tử, và không phải rác toàn bộ #parent
phần tử. Điều này có vẻ giống như một hack, nhưng tôi thực sự thấy nó hoạt động tốt hơn là phải lo lắng về việc kết xuất lại toàn bộ DOM và gắn lại các yếu tố và như vậy. Nếu tôi thực sự muốn làm cho nó sạch sẽ, tôi sẽ tạo một Child
chế độ xem mới (tương tự như InfoView
) sẽ xử lý #name
khối.
Bây giờ đối với các Child
khung nhìn, cái initialization
này khá giống với các Parent
khung nhìn, chỉ cần không tạo ra bất kỳ Child
khung nhìn nào nữa . Vì thế:
- Khởi tạo quan điểm của tôi
- Thiết lập liên kết lắng nghe bất kỳ thay đổi nào đối với mô hình tôi quan tâm
- Hiển thị quan điểm của tôi
Child
xem kết xuất cũng rất đơn giản, chỉ cần kết xuất và thiết lập nội dung của tôi el
. Một lần nữa, không gây rối với phái đoàn hoặc bất cứ điều gì như thế.
Dưới đây là một số mã ví dụ về những gì tôi ParentView
có thể trông như thế nào:
var ParentView = Backbone.View.extend({
el: "#parent",
initialize: function() {
// Step 1, (init) I want to know anytime the name changes
this.model.bind("change:first_name", this.subRender, this);
this.model.bind("change:last_name", this.subRender, this);
// Step 2, render my own view
this.render();
// Step 3/4, create the children and assign elements
this.infoView = new InfoView({el: "#info", model: this.model});
this.phoneListView = new PhoneListView({el: "#phone_numbers", model: this.model});
},
render: function() {
// Render my template
this.$el.html(this.template());
// Render the name
this.subRender();
},
subRender: function() {
// Set our name block and only our name block
$("#name").html("Person: " + this.model.first_name + " " + this.model.last_name);
}
});
Bạn có thể thấy việc thực hiện của tôi subRender
ở đây. Bằng cách thay đổi ràng buộc subRender
thay vì render
, tôi không phải lo lắng về việc nổ tung và xây dựng lại toàn bộ khối.
Đây là mã ví dụ cho InfoView
khối:
var InfoView = Backbone.View.extend({
initialize: function() {
// I want to re-render on changes
this.model.bind("change", this.render, this);
// Render
this.render();
},
render: function() {
// Just render my template
this.$el.html(this.template());
}
});
Các ràng buộc là phần quan trọng ở đây. Bằng cách ràng buộc với mô hình của tôi, tôi không bao giờ phải lo lắng về việc tự gọi render
mình. Nếu mô hình thay đổi, khối này sẽ tự kết xuất lại mà không ảnh hưởng đến bất kỳ chế độ xem nào khác.
Điều PhoneListView
này sẽ tương tự như ParentView
, bạn sẽ chỉ cần thêm một chút logic trong cả chức năng initialization
và render
chức năng của bạn để xử lý các bộ sưu tập. Cách bạn xử lý bộ sưu tập thực sự tùy thuộc vào bạn, nhưng ít nhất bạn sẽ cần lắng nghe các sự kiện của bộ sưu tập và quyết định cách bạn muốn kết xuất (nối / xóa hoặc chỉ hiển thị lại toàn bộ khối). Cá nhân tôi thích nối các khung nhìn mới và xóa các khung nhìn cũ, không hiển thị lại toàn bộ khung nhìn.
Nó PhoneView
sẽ gần giống với InfoView
, chỉ lắng nghe mô hình thay đổi mà nó quan tâm.
Hy vọng rằng điều này đã giúp một chút, xin vui lòng cho tôi biết nếu có gì khó hiểu hoặc không đủ chi tiết.