如何使用Backbone与Twitter REST API?

4
我想从这篇文章Unable to fetch data from Twitter RESTful API using Backbone.js Collection中构建一个简单的Backbone应用程序。我想要做的是添加一个文本框和一个按钮。每次用户按下按钮时,我的应用程序将请求Twitter,并根据文本框内容搜索Twitter(默认情况下,它将搜索“NYC”单词)。
我的代码如下。 我的tweets集合
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请求被Parse捕获在Tweets集合中。没有任何内容添加到我的ul元素。

  2. 第二次点击(带有某个单词):使用该单词进行Twitter请求。但是,上一次调用中的“NYC”推文被打印出来。

  3. 第三次点击(带有其他单词):“第二次点击”的“某个单词”被打印出来。

...

我意识到每次尝试打印我的推文时,我都会得到先前的回复,因为Twitter尚未回复我。我想我可以在parse回调中获取我的推文并将它们打印出来,但这似乎相当恶心。

另一方面,我已经尝试将我的推文绑定到重置事件上,但也没有起作用。

有什么想法吗?。

提前感谢!!


快速更新。如果您想在Backbone 1.0.0中使其工作,似乎必须将{reset: true}传递给this.tweets.fetch - wobh
1个回答

16

这是您的示例代码,使用更符合惯用法的Backbone模式。

基本上:

  • 您有自己的 Tweets 集合
  • 您将事件处理程序绑定到集合的 reset 事件上,以对新填充的集合进行某些操作
  • 在您的视图中,您设置了一个按钮点击事件的事件处理程序,该处理程序调用 collection.fetch() 从“服务器”获取新数据。
  • 当 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/


@tkone。感谢您的建议!我现在会接受他的答案,但是我还没有足够的声望来为他投赞成票:( - Ivan Fernandez
@IvanFernandez 我总是忘记需要声望才能点赞!没关系,我已经给他点赞了 :) - tkone
@Edward,你的代码对我来说是使用Backbone进行搜索和显示的很好的例子。我的问题是,我已经有一个用于结果列表的单独视图。我想重复使用它来进行搜索和显示。你有什么建议吗?另外,在列表中显示结果是否建议有一个单独的视图?谢谢。 - Kim Stacks
2
嗨@EdwardMSmith,jsfiddle中的代码无法工作,有没有可能更新一下? - SoluableNonagon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接