簡體   English   中英

視圖的哪個功能首先執行? 初始化還是渲染?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM