Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Integrating JSON feed with Backbone JS

I'm currently working on a project where I type a keyword inside an input box and when I click send it hits a PHP server with a link like (localhost/json-status.php?query=input text) and it returns whatever is after "query=" in json format. Now I've accomplished this with jQuery and I'm trying to do this again in backbone js.

$("#updateStatus").click(function(){

   var query = $("#statusBar").val();

   var url = "json-status.php" + "?query=" + query;

   $.getJSON(url,function(json){
            $.each(json.posts,function(i,post){
         $("#content").append(
            '<div>'+
               '<p>'+post.status+'</p>'+
            '</div>'
         );
      });
   });
});

I've pretty much ported over what I did in jQuery over to backbone js and it's not working out as expected so far, please let me know if my approach is correct and how I can solve my problem.

backbone code:

(function ($) {
   Status = Backbone.Model.extend({
      status: null
   });

   StatusList = Backbone.Collection.extend({
      initialize: function (models, options) {
         this.bind("add", options.view.addStatusList);
      }
   });

   AppView = Backbone.View.extend({
      el: $("body"),
      initialize: function () {
         this.status = new StatusList( null, { view: this });
      },
      events: {
         "click #updateStatus":   "getStatus",
      },
      getStatus: function () {
         var url = "json-status.php" + "?query=" + $("#statusBar").val();
         var statusModel;

         $.getJSON(url,function(json){
            $.each(json.posts,function(i,post){
               statusModel = new Status({ status: post.status });
               this.status.add( statusModel );
            });
         });
      },
      addStatusList: function (model) {
         $("#status").prepend("<div>" + model.get('status') + "</div>");
      }
   });

   var appview = new AppView;
})(jQuery);

PHP server code which returns in json format (this works fine):

<?php
    $getQuery = $HTTP_GET_VARS["query"];

    $json='
    {"posts":[
        {
            "status": "' . $getQuery . '"
        }
    ]}
    ';
    echo $json;
?>

And if you wish to copy/paste what I have so far it's:

<!DOCTYPE html>
<html>
<head>
    <title>JSON Test</title>
</head>
<body>

    <input value="What's on your mind?" id="statusBar" /><button id="updateStatus">Update Status</button>

    <div id="content">

    </div>

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
    <script src="http://ajax.cdnjs.com/ajax/libs/underscore.js/1.1.4/underscore-min.js"></script>
    <script src="http://ajax.cdnjs.com/ajax/libs/backbone.js/0.3.3/backbone-min.js"></script>

    <script type="text/javascript">
        $("#statusBar").click(function() {
            $(this).val("");
        });

        (function ($) {
            Status = Backbone.Model.extend({
                status: null
            });

            StatusList = Backbone.Collection.extend({
                initialize: function (models, options) {
                    this.bind("add", options.view.addStatusList);
                }
            });

            AppView = Backbone.View.extend({
                el: $("body"),
                initialize: function () {
                    this.status = new StatusList( null, { view: this });
                },
                events: {
                    "click #updateStatus":  "getStatus",
                },
                getStatus: function () {
                    var url = "json-status.php" + "?query=" + $("#statusBar").val();
                    var statusModel;

                    $.getJSON(url,function(json){
                        $.each(json.posts,function(i,post){
                            statusModel = new Status({ status: post.status });
                            this.status.add( statusModel );
                        });
                    });
                },
                addStatusList: function (model) {
                    $("#status").prepend("<div>" + model.get('status') + "</div>");
                }
            });

            var appview = new AppView;
        })(jQuery);
    </script>

</body>
</html>

Thank you for your time.


Julien's code.

StatusList = Backbone.Collection.extend({
    model: Status,
    value: null,
    url: function(){ return "json-status.php?query=" + this.value;}
});

AppView = Backbone.View.extend({
    el: $("body"),
    initialize: function () {
        _.bindAll(this, "render");// to solve the this issue
        this.status = new StatusList( null, { view: this });
        this.status.bind("refresh", this.render);
    },
    events: {
        "click #updateStatus" :"getStatus",
    },
    getStatus: function () {
        this.status.value =  $("#statusBar").val();
        this.status.fetch(this.status.value);
    },
    render: function () {
        var statusEl = $("#status");
        this.status.each( function(model) {
            statusEl.prepend("<div>" + model.get('status') + "</div>");
        });
    }
});

var appview = new AppView;

Full HTML (part 2):

<!DOCTYPE html>
    <html>
    <head>
        <title>JSON Test</title>
    </head>
    <body>

        <input value="What's on your mind?" id="statusBar" />
        <button id="updateStatus">Update Status</button>

        <div id="status">

        </div>

        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
        <script src="http://ajax.cdnjs.com/ajax/libs/underscore.js/1.1.4/underscore-min.js"></script>
        <script src="http://ajax.cdnjs.com/ajax/libs/backbone.js/0.3.3/backbone-min.js"></script>

        <script type="text/javascript">
            $("#statusBar").click(function() {
                $(this).val("");
            });

            Status = Backbone.Model.extend();

            StatusList = Backbone.Collection.extend({
                model: Status,
                value: null,
                url: function(){ return "json-status.php?query=" + this.value;}
            });

            AppView = Backbone.View.extend({
                el: $("body"),
                initialize: function () {
                    _.bindAll(this, "render");// to solve the this issue
                    this.status = new StatusList( null, { view: this });
                    this.status.bind("refresh", this.render);
                },
                events: {
                    "click #updateStatus" :"getStatus",
                },
                getStatus: function () {
                    this.status.value =  $("#statusBar").val();
                    this.status.fetch(this.status.value);
                },
                render: function () {
                    var statusEl = $("#status");
                    this.status.each( function(model) {
                        statusEl.prepend("<div>" + model.get('status') + "</div>");
                    });
                }
            });

            var appview = new AppView;

        </script>

    </body>
    </html>

And the PHP is still the same from the one originally documented.

like image 590
Nej Kutcharian Avatar asked Apr 12 '11 03:04

Nej Kutcharian


People also ask

Is Backbone JS still relevant?

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.

Is Backbone deprecated?

No, Backbone. js is not dead. The developers should make use of Backbone JS while developing a single-page Java application. Backbone JS features Model View Framework, which allows much more than structuring JavaScript architecture.

Is Backbone JS frontend or backend?

Backend Synchronization BackboneJS is use with the front-end and back-end systems, allows the synchronization with the backend to provide support to RESTful APIs.

Does Backbone need jQuery?

You can use the Backbone. Model without jQuery, but Backbone. View will require either jQuery or Zepto, just like the docs state.


2 Answers

As for your general design, you should use a Backbone.Model and Collection to fetch your statuses:

Status = Backbone.Model.extend();

StatusList = Backbone.Collection.extend({
  model: Status,
  value: null
  url: function(){ return "json-status.php" + "?query=" + this.value;
});

Your view should be listening to the StatusList and not the StatusList creating a binding to the view:

AppView = Backbone.View.extend({
  el: $("body"),
  initialize: function () {
    _.bindAll(this, "render");// to solve the this issue
    this.status = new StatusList( null, { view: this });
    this.status.bind("refresh", this.render);
  },
  events: {
    "click #updateStatus":  "getStatus",
  },
  getStatus: function () {
    this.status.value =  $("#statusBar").val();
    this.status.fetch()
  },
  render: function () {
    var statusEl = $("#status")
    this.status.each( function(model){
      statusEl.prepend("<div>" + model.get('status') + "</div>");
    }
  }
});

There is a couple of things here:

  • an attribute on the model is defined by set/get not by a js attributes like you did with status
  • try to decouple stuff views know about models but models do not know about views
like image 52
Julien Avatar answered Oct 02 '22 23:10

Julien


FYI (from the documentation)

We've taken the opportunity to clarify some naming with the 0.5.0 release. Controller is now Router, and refresh is now reset.

So if you are using the latest version dont forget to change refresh to reset in this line:

this.status.bind("refresh", this.render);
like image 38
Milan Korsos Avatar answered Oct 02 '22 22:10

Milan Korsos