[英]Which function of a view gets executed first? initialize or render?
我在下面的代碼中插入了三個console.log
,它們來自教程Your First Backbone.js App 。
我的問題是:為什么console.log(this.el)
顯示元素的innerHtml已經被“渲染”了,但是console.log('render runs!')
running console.log('render runs!')
消息在其后打印出來了?
視圖的哪個功能首先執行? 初始化還是渲染?
$(function(){
// Create a model for the services
var Service = Backbone.Model.extend({
// Will contain three attributes.
// These are their default values
defaults:{
title: 'My service',
price: 100,
checked: false
},
// Helper function for checking/unchecking a service
toggle: function(){
this.set('checked', !this.get('checked'));
}
});
// Create a collection of services
var ServiceList = Backbone.Collection.extend({
// Will hold objects of the Service model
model: Service,
// Return an array only with the checked services
getChecked: function(){
return this.where({checked:true});
}
});
// Prefill the collection with a number of services.
var services = new ServiceList([
new Service({ title: 'web development', price: 200}),
new Service({ title: 'web design', price: 250}),
new Service({ title: 'photography', price: 100}),
new Service({ title: 'coffee drinking', price: 10})
// Add more here
]);
// This view turns a Service model into HTML
var ServiceView = Backbone.View.extend({
tagName: 'div',
events:{
'click': 'toggleService'
},
initialize: function(){
// Set up event listeners. The change backbone event
// is raised when a property changes (like the checked field)
console.log(this);
console.log(this.el);
this.listenTo(this.model, 'change', this.render);
},
render: function(){
// Create the HTML
console.log("render runs!");
this.$el.html('<input type="checkbox" value="1" name="' + this.model.get('title') + '" /> ' + this.model.get('title') + '<span>$' + this.model.get('price') + '</span>');
this.$('input').prop('checked', this.model.get('checked'));
// Returning the object is a good practice
// that makes chaining possible
return this;
},
toggleService: function(){
this.model.toggle();
}
});
// The main view of the application
var App = Backbone.View.extend({
// Base the view on an existing element
el: $('#main'),
initialize: function(){
// Cache these selectors
this.total = $('#total span');
this.list = $('#services');
// Listen for the change event on the collection.
// This is equivalent to listening on every one of the
// service objects in the collection.
this.listenTo(services, 'change', this.render);
// Create views for every one of the services in the
// collection and add them to the page
services.each(function(service){
var view = new ServiceView({ model: service });
this.list.append(view.render().el);
}, this); // "this" is the context in the callback
},
render: function(){
// Calculate the total order amount by agregating
// the prices of only the checked elements
var total = 0;
_.each(services.getChecked(), function(elem){
total += elem.get('price');
});
// Update the total price
this.total.text('$'+total);
return this;
}
});
new App();
});
控制台的輸出如下:
child {cid: "view7", model: child, $el: init[1], el: div}
<div>
<input type="checkbox" value="1" name="web development"> web development
<span>$200</span></div>
render runs!
initialize
始終被調用,因為它位於默認Backbone的視圖構造函數中。
每次您手動調用render
時都會調用它。
services.each(function(service) {
// ServiceView 'initialize' is called here.
var view = new ServiceView({ model: service });
// ServiceView 'render' is called here.
this.list.append(view.render().el);
}, this);
el
? 實際上,控制台在呈現之前不會顯示該元素,但是在控制台中對其進行檢查時會對其進行評估。
這是一個簡單的例子:
var myObject = {};
console.log(myObject);
myObject.test = "value";
如果您不得不猜測,您會說記錄了一個空對象,這不會是完全錯誤的。
小藍!
說:
左邊的對象值在登錄時被快照,下面的值剛剛被評估。
如“畝太短”所述,
控制台包含實時引用 ,不復制任何內容。 因此,當您進入控制台查看
this.el
,它將顯示this.el
現在是什么,而不是評估console.log(this.el)
時的狀態。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.