Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Connecting predefined HTML to Models and Views in Backbone

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 is important and I want to keep it like this.

Say this is (part of) my HTML:

<div class="pig" data-id="1">
    <h1>Harry</h1>
    <input type="text" value="Harry">
</div>
<div class="pig" data-id="2">
    <h1>Jill</h1>
    <input type="text" value="Jill">
</div>
<div class="pig" data-id="3">
    <h1>Bob</h1>
    <input type="text" value="Bob">
</div>

Now the idea is that when you change the input this should update my Backbone Model and render the view, resuling in the h1 being updated with the new name. I'm not sure how I should set up my models and views.

I kind of have the structure of my models and my views, but I don't know how I should use them.

At the moment I have something like this:

var PigModel = Backbone.Model.extend()
var pigs = new PigModel()
pigs.reset([
    {"id": "1", "name": "Harry"},
    {"id": "2", "name": "Jill"},
    {"id": "3", "name": "Bob"}
])

var PigView = Backbone.View.extend({
    el: '.pig',
    events: {
        'change input': function() {
            // update appropriate Model ?
            this.render()
        }
    },
    render: function() {

        var new_name = // get new name from model ?

        var pig_template = _.template($('#pig_template').html())
        var new_contents = pig_template({ name: new_name })

        // render only the pig that was changed ?

    }
})

So at the places where I added comments in the code I don't know what to do:

  • At the change event, how do I find the model that belongs to this view? I could loop through all the models but that seems inefficient.
  • Again in the render method, how do I get the model that belongs to this view?
  • In the render method, how can I only render the pig view the event was on, and not render all the pigs?

Maybe I'm going for a total wrong approach over here. If so, please point me in the right direction.

like image 985
gitaarik Avatar asked Jul 16 '13 22:07

gitaarik


People also ask

Which is considered the backbone of any HTML document?

js (aka Backbone) is designed to add structure to client-side applications, to avoid a spaghetti-code mess.

What are views in Backbone JS?

In backbone. js, there are 7 modules HTTP request, Router, View, Events, Model, and Collection. Whenever a user makes a request it is directed to the router and in response to these requests, a user interface is displayed at the user end which is known as Views.

What is backbone in programming?

Backbone. js is a model view controller (MVC) Web application framework that provides structure to JavaScript-heavy applications. This is done by supplying models with custom events and key-value binding, views using declarative event handling and collections with a rich application programming interface (API).

Is Backbone JS still used?

Backbone. Backbone has been around for a long time, but it's still under steady and regular development. It's a good choice if you want a flexible JavaScript framework with a simple model for representing data and getting it into views.


1 Answers

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.

like image 136
gitaarik Avatar answered Sep 22 '22 10:09

gitaarik