视图的哪个功能首先执行?初始化还是渲染? [英] Which function of a view gets executed first? initialize or render?

查看:92
本文介绍了视图的哪个功能首先执行?初始化还是渲染?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在以下代码中插入了三个console.log,这些代码来自教程您的第一个Backbone.js应用程序.

I inserted three console.log into the following code, which is from the tutorial Your First Backbone.js App.

我的问题是:为什么console.log(this.el)显示元素的innerHtml已经被渲染",但是console.log('render runs!')消息会在其后打印?

My question is: why console.log(this.el) shows the element's innerHtml is already "rendered" but the console.log('render runs!') message prints after it?

首先执行哪个View函数?初始化还是渲染?

Which function of the View gets executed first? initialize or render?

$(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的视图构造函数中.

initialize is always called first as it's inside the default Backbone's view constructor.

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?

实际上,控制台在渲染之前不会显示该元素,但是当您在控制台中对其进行检查时会对其进行评估.

Why the console shows the el before rendering?

In fact, the console doesn't show the element before rendering, but it is evaluated when you check it in the console.

这是一个简单的例子:

var myObject = {};

console.log(myObject);

myObject.test = "value";

如果您不得不猜测,您会说记录了一个空对象,这不会是完全错误的.

If you had to guess, you'd say that an empty object is logged and you wouldn't be totally wrong.

蓝色的小!说:

左边的对象值在登录时被快照,下面的值刚刚被评估.

Object value at left was snapshotted when logged, value below was evaluated just now.

如"mu is too short"所述,

As mentioned by "mu is too short",

控制台包含实时引用,并且不会复制任何内容.因此,当您进入控制台查看this.el时,它显示的是this.el现在是什么,而不是在评估console.log(this.el)时是什么.

the console contains live references and doesn't copy anything. So when you get to the console to look at this.el, it shows you what this.el is right now rather than what it was when console.log(this.el) was evaluated.

这篇关于视图的哪个功能首先执行?初始化还是渲染?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆