backbone view self render

if you want your views to handle the templates, and update self

by Antonimo

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/json2/20121008/json2.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/handlebars.js/1.0.rc.2/handlebars.min.js"></script>
<script src="http://backbonejs.org/backbone.js"></script>
<button type="button" id="do1">change model.type of g.box</button>
<button type="button" id="put1">put</button>
<div id="container"></div>
<script type="text/x-template" id="type1-template">
    <div class = "test1class" > 
        {{offer}} 
        <button type = "button"
    class = "button" > delete </button>
	</div>
</script>
<script type="text/x-template" id="type2-template">
    <div class = "test2class" > 
        {{offer}}
        <button type = "button"
    class = "button" > delete </button>
	</div>
</script>
<script>
    var g = {};
    g.count = 0;
    g.$container = $('#container');
    var template = function(name) {
        return Handlebars.compile($('#' + name + '-template').html());
    };

    $(function() {

        g.box = new App.Box();
        g.view = new App.BoxView({
            model: g.box
        });
        g.$container.append(g.view.$el);
    
        $("#do1").click(function(){
            g.count++;
            if( g.box.get('type') == 1 ){
                g.box.set({type:"2", offer:"change:"+g.count});
            } else {
                g.box.set("type", "1");
            }
        });
        $("#put1").click(function(){
            g.box = new App.Box();
            g.view = new App.BoxView({
                model: g.box
            });
            g.$container.append(g.view.$el);
        });
    });
</script>

CSS

.test1class {
    background: #D8D5D2;
}
.test2class {
    background: #D8D500;
}

JavaScript

$(function () {
    App = {};
    App.Box = Backbone.Model.extend({
        defaults: function () {
            return {
                offer: "empty ...",
                type: 1 // 1: text, 2: media
            };
        },
        initialize: function () {
            this.on('all', function (e) {
                console.log("■ Box event: " + e);
            });
        }
    });

    App.BoxView = Backbone.View.extend({
        template: {},
        templates: { // Шаблоны на разное состояние
            "1": template('type1'),
                "2": template('type2')
        },
        events: {
            'click .button': 'deleteView'
        },
        initialize: function (options) {
            this.on('all', function (e) {
                console.log(this.get('name') + "$. event: " + e);
            });
            this.listenTo(this.model, 'change', this.render);
            this.listenTo(this.model, 'destroy', this.remove);
            this.render();
            return this; // ?
        },
        render: function () {
            this.template = this.templates[this.model.get('type')];
            var t_$el = this.$el;
            this.$el = $($.parseHTML(this.template(this)));
            this.$el.attr("id", this.cid);
            //console.log( 't_$el in dom: ', t_$el.parent().length );
            //t_$el.each(function(index, el){ 
                //console.log(index, $(el).parent().length) })
            if (t_$el.parent().length !== 0) { // if in dom
                //console.log( 'clean' );
                this.undelegateEvents();
                t_$el.each(function(index, el){ // clean up
                    console.log( index, el, this );
                    if( index !== 0 ){ 
                        //console.log('removed');
                        $(el).remove();
                    }
                });
                //t_$el.first().replaceWith(this.$el);
                //t_$el.each(function(index, el){ 
                //   ...