Connecting predefined HTML to Models and Views in Backbone

后端 未结 3 1252
走了就别回头了
走了就别回头了 2021-01-02 18:56

I\'m starting out with Backbone.js so I must say I\'m not yet very familiar with the concepts.

I have predefined HTML and I want to use Backbone to manage this. This

相关标签:
3条回答
  • 2021-01-02 19:21

    Ok, I managed to figure it out.

    The idea is to loop through your existing HTML using jQuery, then creating instances of views and models of it using the jquery selectors and the preloaded json.

    HTML:

    <div class="pig">
        <h1>Harry</h1>
        <input type="text" value="Harry" />
    </div>
    <div class="pig">
        <h1>Jill</h1>
        <input type="text" value="Jill" />
    </div>
    <div class="pig">
        <h1>Bob</h1>
        <input type="text" value="Bob" />
    </div>
    

    Javascript:

    $(function() {
    
        var PigModel = Backbone.Model.extend()
    
        var PigView = Backbone.View.extend({
            events: {
                'change input': function(e) {
                    this.model.set('name', e.currentTarget.value)
                    this.render()
                }
            },
            render: function() {
                this.$el.html(
                    '<h1>' + this.model.get('name') + '</h1>' +
                    '<input type="text" value="' + this.model.get('name') + '" />'
                )
            }
        })
    
        var pig_data = [
            {"name": "Harry"},
            {"name": "Jill"},
            {"name": "Bob"}
        ]
    
    
        // the magic starts here
    
        var pig_number = 0
    
        $('.pig').each(function() {
    
            new PigView({
                el: this,
                model: new PigModel(pig_data[pig_number])
            })
    
        })
    
    })
    

    Jsfiddle: http://jsfiddle.net/tU3Mt/1/

    Like this I can serve a complete HTML page from the server, then load the desired elements into my backbone views/models and manage them from there.

    About wether this is the way backbone should be used or not: It may not be the most logical/efficient way to do this from a developer point of view. However, I think this approach has some important benefits:

    • The client get's HTML served directly and won't have to process any javascript before the page can be presented. This will become more noticable as your HTML gets bigger/more complex.
    • Search engines/web crawlers can read your page because it serves the complete HTML.

    For some people these points may not be that important, because a webapp will be fast after it has been loaded and search engines won't have to crawl it. However in some situations you might have a mix of a website and a webapp, where the page needs to load fast, be crawlable but also have a responsive interface which is complex enough to make a developer want to use something like backbone. If somebody has other ideas about this I sure like to hear them.

    0 讨论(0)
  • 2021-01-02 19:37

    I would take a little bit of a different approach. Create a collection of Pig models. Have a view that knows how to render a single pig, PigView. Let it be responsible for updating the one pig and it's corresponding h1. Have a higher level view that renders the collection of pigs into whatever parent element you want.

    var PigModel = Backbone.Model.extend()
    // You want a collection of pig models
    var pigs = new Backbone.Collection([
        {"id": "1", "name": "Harry"},
        {"id": "2", "name": "Jill"},
        {"id": "3", "name": "Bob"}
    ], {model: PigModel});
    
    var PigView = Backbone.View.extend({
        // Want to set the class for the generated el not pass a selector
        className : "pig",
        // Dummy template from your markup in question
        template : function (modelAttrs) {
            return "<h1>"+modelAttrs.name+"</h1><input type='text' value='"+modelAttrs.name+"'>";
        },
        events: {
            'change input': function(e) {
                // You have a reference to the model through this
                this.model.set({name : e.currentTarget.value});
                this.render();
            }
        },
        // Bare bones render
        render: function() {
            this.$el.html(this.template(this.model.attributes));
            return this;
        }
    });
    
    // Parent view for responsible for rendering the collection of pigs somewhere.
    var HigherLevelView = Backbone.View.extend({
        render : function () {
            pigs.each(function (pig) {
                this.$el.append(new PigView({model : pig}).render().el);
            });
        }
    });
    
    $("body").append(new HigherLevelView().render().el);
    

    Fiddle

    0 讨论(0)
  • 2021-01-02 19:37

    Attach to existing html is possible, but it is not very common approach. Because of that, there is almost no real info on this :(

    You could try to follow steps described in following article: http://lostechies.com/derickbailey/2011/09/26/seo-and-accessibility-with-html5-pushstate-part-2-progressive-enhancement-with-backbone-js/

    Idea is, to add some data-attribute into rendered html, so you will be able to match model with rendered html.

    0 讨论(0)
提交回复
热议问题