Ajax从Backbone调用GitHub API

时间:2014-05-28 01:40:00

标签: javascript ajax json backbone.js github-api

我正在探索Backbone,并且在尝试从GitHub API中检索JSON 时遇到了问题。我正在创建一个快速的Web应用程序,以从GitHub Rails仓库中检索打开的问题的分页列表。我挂断电话的地方就是检索包含第一页问题的JSON(暂时忘记分页)。

我可以通过一个简单的jQuery Ajax调用获得第一页的问题,但这不能正确使用Backbone。

$.getJSON("https://api.github.com/repos/rails/rails/issues?state=open", function(data) {...});

以下是我的 Backbone JavaScript - 此时更容易处理所有文件。

$(function() {
    // Define namespace as RailsIssues
    window.RailsIssues = {
        Models: {},
        Collections: {},
        Views: {}
    };

    // Global function to simplify template property syntax
    window.template = function(id){
        return _.template( $('#' + id).html());
    }

    // Issue model
    RailsIssues.Models.Issue = Backbone.Model.extend({
    });

    // IssueList collection
    RailsIssues.Collections.Issues = Backbone.Collection.extend({
        model: RailsIssues.Models.Issue,

        /* not getting anything back */
        url: "https://api.github.com/repos/rails/rails/issues",

        parse: function(data){
            return data;
        }
    });

    // Issue view
    RailsIssues.Views.Issue = Backbone.View.extend({
        tagname: 'li',
        template: template('issueTemplate'),
        initialize: function(){
            this.render();
        },
        render: function(){
            this.$el.html(this.template(this.model.toJSON()));
            return this;
        }
    });

    // Issues view
    RailsIssues.Views.Issues = Backbone.View.extend({
        template: template('issuesTemplate'),
        render: function(eventName) {
            _.each(this.model, function(issue) {
                var number = issue.attributes['number'];
                //var title = issue.attributes['title'];
                var xtemplate = this.template(issue.toJSON());
                $(this.el).append(xtemplate);
                }, this);

            return this;
        }
    });

    Backbone.sync = function(method, model) {
        alert(method + ": " + model.url);
    }

    var issuesView = new RailsIssues.Views.Issues({ collection: RailsIssues.Views.Issues });
    $(document.body).append(issuesView.render().el);
});

这是我的 HTML - 除了资源之外,这里真的没什么兴趣。我只是试图获取数据并在此时将其推入文档正文 - 样式将在稍后出现。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <script id="issuesTemplate" type="text/template">
          <li><%= number %></li>
      </script>
      <script src="script/underscore.js"></script>
      <script src="script/jquery-1.11.1.min.js"></script>
      <script src="script/backbone.js"></script>
          <script src="script/script.js"></script>
        <title>Rails Issues</title>
    </head>
    <body>
        <header>
            Open Issues in Rails GitHub
        </header>
    </body>
</html>

尝试检索JSON数据时我缺少什么?代码只是默默地失败,什么都不返回,而我上面的jQuery确实返回了所需的JSON。你能提出的任何建议都会非常有用。

2 个答案:

答案 0 :(得分:2)

我无法弄清楚我的问题中显示的代码错误,但在this excellent tutorial的帮助下,我终于能够使Ajax API调用正常工作。

此代码仅检索结果的第一页(Rails GitHub page上发布的问题),并在无序列表中显示问题编号。

以下是HTML,其中包含正确顺序的模板和脚本标记:

<!DOCTYPE html lang="en">
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="icon" type="image/x-icon" href="https://assets-cdn.github.com/favicon.ico">      

         <script id="issuesTemplate" type="text/template">
            <% $.each(issues, function() { %>
                <li><%= this.number %></li>
            <% }); %>          
        </script>       

        <script src="script/underscore.js"></script>
        <script src="script/jquery-1.11.1.min.js"></script>
        <script src="script/backbone.js"></script>
        <script src="script/script.js"></script>
        <title>Rails Issues</title>   
    </head>
    <body>
        <header>
            Open Issues in Rails GitHub
        </header>
        <div class="theList">Loading... Please Wait.</div>
    </body>
</html>  

这是script.js文件

var RI = {
    run: function() {
        this.listview = new this.listView();
        this.issuescollection = new RI.issuesCollection();
        this.router = new this.Router();
        Backbone.history.start();
        this.router.navigate('list_issues');
    }
};

RI.Router = Backbone.Router.extend({
    routes: {
        'list_issues': 'renderListIssuesPage'
    },

    renderListIssuesPage: function () {
        RI.listview.setElement('div.theList');
        RI.listview.listIssuesPage();
    }
});

RI.issueModel = Backbone.Model.extend({

});

RI.issuesCollection = Backbone.Collection.extend({
    model: RI.issueModel,   
    url: 'https://api.github.com/repos/rails/rails/issues'
}); 

RI.listView = Backbone.View.extend({
    el: 'div.theList',

    template: _.template($('#issuesTemplate').html()),

    initialize: function () {
        _.bindAll(this, 'listIssuesPage', 'render');
    },

    render: function (response) {
        var self = this;

        this.$el.html(this.template({issues: response}));
    },

    listIssuesPage: function (querystring) {
        var self = this;

        RI.issuescollection.fetch({
            data: querystring,
            success: function(collection, response) {
                self.render(response);
            }
        });
    }
});

$(function() {
    RI.run();
}); 

答案 1 :(得分:1)

我尝试运行您的代码,但错过了issuesTemplateissueTemplate,但是我注意到您实例化了视图,但从未实现过集合或模型。相反,您已将视图集合指向视图问题的定义(但不是集合实例):

var issuesView = new RailsIssues.Views.Issues({ collection: RailsIssues.Views.Issues });

此外,在创建新集合后,您需要调用fetch()以使Backbone执行API调用以收集所需的JSON。我建议做的事情如下:

var issuesCollection = new RailsIssues.Collections.Issues();
issuesCollection.fetch();  // makes the GET request
var issuesView = new RailsIssues.Views.Issues({ collection: issuesCollection });