4

この投稿から単純なBackboneアプリを構築しようとしています。Backbone.jsコレクションを使用してTwitterRESTfulAPIからデータをフェッチできません。私がやりたいのは、テキストボックスとボタンを追加することです。ユーザーがボタンを押すたびに、私のアプリはTwitterをリクエストし、テキストボックスの内容に基づいてTwitterで検索します(デフォルトでは「NYC」という単語を検索します)。

私のコードは次のとおりです。

私のツイートコレクション

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': '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();

事は:

  1. 最初のクリック(空のテキストボックス):Twitterリクエストは、ツイートコレクション内の解析によってキャプチャされます。私のul要素には何も追加されていません。

  2. 2回目のクリック(単語を含む):Twitterのリクエストはその単語を使用して行われます。ただし、前回の呼び出しからの「NYC」ツイートは出力されます。

  3. 3回目のクリック(他の単語を含む):2回目のクリックからの「いくつかの単語」が出力されます。

...。

Twitterがまだ返信していないので、ツイートを印刷しようとするたびに前回の返信が届きます。解析コールバックでツイートを取得して出力できたと思いますが、かなり厄介なようです。

一方、ツイートをリセットイベントにバインドしようとしましたが、どちらも機能しません。

何か案は??。

前もって感謝します!!

4

1 に答える 1

16

これは、よりイディマティックなバックボーンパターンで実行されたサンプルコードです。

基本的に:

  • ツイートコレクションがあります
  • reset新しく入力されたコレクションで何かを行うコレクションのイベントにイベントハンドラーをバインドします
  • ビューでは、「サーバー」から新しいデータを取得するためにclick呼び出すボタンイベントのイベントハンドラーを設定します。collection.fetch()
  • フェッチが完了すると、resetイベントがトリガーされ、イベントにバインドされたイベントハンドラーが呼び出されresetます。

コード:

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();

試してみる実例:http: //jsfiddle.net/38L35/16/

于 2012-04-06T21:09:21.563 に答える