2012-04-06 6 views
4

Ich versuche, eine einfache Backbone-App von diesem Beitrag Unable to fetch data from Twitter RESTful API using Backbone.js Collection zu bauen. Was ich tun möchte, ist ein Textfeld und eine Schaltfläche hinzufügen. Jedes Mal, wenn ein Benutzer eine Taste drückt, fordert meine App zu twittern und wird in Twitter basierend auf dem Inhalt der Textbox suchen (es wird das Wort "NYC" als Standard suchen).Wie benutzt man Twitter Rest API mit Backbone?

Mein Code ist wie folgt.

Meine Tweets Sammlung

var Tweets = Backbone.Collection.extend({ 
    model: Tweet, 
    url: 'http://search.twitter.com/search.json?q=NYC&callback=?', 
    parse: function(response) { 
     console.log('parsing ...') 
     return response.results; 
    } 
}); 

Meine Ansicht.

var PageView = Backbone.View.extend({ 
    el: $('body'), 
    events: { 
    'click button#add': 'addItem' 
    }, 
    initialize: function() { 
     _.bindAll(this, 'render', 'addItem'); 
     this.tweets = new Tweets(); 
     this.counter = 0; 
     this.render(); 
    }, 
    render: function() { 
     $(this.el).append("<input id= 'search'type='text' placeholder='Write a word'></input>"); 
     $(this.el).append("<button id='add'>Search twitts</button>"); 
     $(this.el).append("<ul id='tweets'></ul>"); 
     return this; 
    }, 
    addItem: function(item) { 
     var subject = $('#search').val() || 'NYC'; 
     this.tweets.url = 'http://search.twitter.com/search.json?q=' + subject + '&callback=?'; 

     // never called ... 
     this.tweets.bind('reset', function(collection) { 
      console.log(collection.length); 
      alert(collection.length); 
     }); 


     $.each(this.tweets.fetch().models, function(index, tweet) { 
      item = new Tweet(); 
      item.set({ 
       order: this.counter, 
       info: tweet.attributes.text// modify item defaults 
      }); 
      $('ul', this.el).append("<li>" + item.get('order') + " " + item.get('info') + "</li>"); 
     }); 

    } 
}); 
var pageView = new PageView(); 

Die Sache ist die:

  1. Klicken Sie zuerst (leere Textbox): twitter Anfrage von Parse innerhalb Tweets Sammlung erfasst wird. Nichts wird an mein ul-Element angehängt.

  2. Zweiter Klick (mit einem Wort): twitter Anfrage wird mit diesem Wort gemacht. Es werden jedoch "NYC" -Tweets vom vorherigen Anruf gedruckt.

  3. Dritter Klick (mit einem anderen Wort): 'Ein Wort' aus dem zweiten Klick werden gedruckt.

....

Ich weiß, dass jedes Mal wenn ich versuche, meine Tweets ich die vorherige Antwort erhalten zu drucken, weil Twitter mir noch nicht geantwortet. Ich nehme an, dass ich meine Tweets im Parse-Callback bekommen und ausdrucken konnte, aber es scheint ziemlich eklig zu sein.

Auf der anderen Seite habe ich versucht, meine Tweets binden sie an die Reset-Ereignis, aber es funktioniert auch nicht.

Irgendwelche Ideen ??.

Vielen Dank im Voraus!

+0

kurzem Update. Wenn Sie möchten, dass dies in Backbone 1.0.0 funktioniert, müssen Sie '{reset: true}' an 'this.tweets.fetch' übergeben. – wobh

Antwort

16

Hier ist Ihr Beispielcode in einem idimatic Backbone-Muster.

Grundsätzlich gilt:

  • Sie haben Ihre Tweets Sammlung
  • Sie binden einen Event-Handler an die reset Veranstaltung Sammlung, die etwas mit dem neu besiedelten Sammlung
  • Ihrer Ansicht nach der Fall ist, setzen Sie ein Ereignis auf Handler für Ihre Schaltfläche - click Ereignis, das collection.fetch() ruft, um neue Daten vom "Server" zu erhalten.
  • Wenn der Abruf abgeschlossen ist, wird das Ereignis reset ausgelöst und der Ereignishandler aufgerufen, der an das Ereignis reset gebunden ist.

Code:

var Tweet = Backbone.Model.extend(); 

var Tweets = Backbone.Collection.extend({ 
    model: Tweet, 
    url: 'http://search.twitter.com/search.json?q=NYC&callback=?', 
    parse: function(response) { 
     console.log('parsing ...') 
     return response.results; 
    } 
}); 
var PageView = Backbone.View.extend({ 
    el: $('body'), 
    events: { 
     'click button#add': 'doSearch' 
    }, 
    initialize: function() { 
     _.bindAll(this, 'render', 'addItem'); 
     this.tweets = new Tweets(); 
     _this = this; 
     // Bind an event handler for the reset event. 
     this.tweets.bind('reset', function(collection) { 
      // Clear any old tweet renderings 
      _this.$('#tweets').empty(); 
      // For each tweet in the collection, we call addItem and 
      // and pass the tweet. 
      collection.each(function(tweet) { 
       _this.addItem(tweet); 
      }); 
     }); 
     this.counter = 0; 
     this.render(); 
    }, 
    // This function is the event handler for the button click. 
    // It tells the Tweets collection to fetch() 
    doSearch: function() { 
     var subject = $('#search').val() || 'NYC'; 
     this.tweets.url = 'http://search.twitter.com/search.json?q=' + subject + '&callback=?'; 
     this.tweets.fetch(); 
    }, 
    render: function() { 
     $(this.el).append("<input id= 'search'type='text' placeholder='Write a word'></input>"); 
     $(this.el).append("<button id='add'>Search twitts</button>"); 
     $(this.el).append("<ul id='tweets'></ul>"); 
     return this; 
    }, 
    addItem: function(item) { 
     console.log(item); 
     $('ul', this.el).append("<li><b>" + item.get('from_user_name') + "</b>: " + item.get('text') + "</li>"); 

    } 
}); 
var pageView = new PageView(); 

Live-Beispiel mit spielen: http://jsfiddle.net/38L35/16/

+0

Genau das brauche ich! Danke für Ihre Hilfe. :) –

+0

@IvanFernandez akzeptieren seine Antwort und oben abstimmen, wenn dies funktioniert – tkone

+0

@ tkone. Danke für deinen Vorschlag!!. Ich werde seine Antwort jetzt akzeptieren, aber ich habe noch nicht genug Reputation, um ihn zu wählen :( –

Verwandte Themen