Backbone.js:填充我的 collection,然后将其附加到页面

Backbone.js: Populating my collection and then appending it to the page

我在 backbone.js 工作。在下面的代码中,我正在调用 Nutritionix API,以便用 JSON 响应填充我的 collection。我在填充 collection 并将结果附加为列表时遇到问题。我这样做是为了测试我的 collection 是否已正确填充并测试它是否会附加到页面。但是,当我在浏览器中测试代码时,我没有看到 field[brand_name] 属性附加到页面。我的 collection 是否正确填充?我怎样才能看到附加到页面的上述属性?我的代码有什么问题?

这是我的 Javascript:

$(function(){

    var SearchList = Backbone.Collection.extend({
        url: "https://api.nutritionix.com/v1_1/search/taco?results=0%3A20&cal_min=0&cal_max=50000&fields=item_name%2Cbrand_name%2Citem_id%2Cbrand_id&appId=26952a04&appKey=78e2b31849de080049d26dc6cf4f338c",

        initialize: function(){
            this.bind("reset", function(model, options){
            console.log("Inside event");
            console.log(model);
            });
        }

    });

    var terms = new SearchList();

    terms.fetch({
        success: function(response,xhr) {
             console.log("Inside success");
             console.log(response.toJSON());
        },
        ERROR: function (errorResponse) {
               console.log(errorResponse)
        }
    });


    // The main view of the application
    var App = Backbone.View.extend({

        // Base the view on an existing element
        el: $('.container'),

        initialize: function(){

            this.listenTo(this.model, 'sync', this.render);

            // Cache these selectors
            // this.total = $('#total span');
            this.list = $('#listing');


        },

        render: function(){

            // Calculate the total order amount by agregating
            // the prices of only the checked elements
            terms.each(function(term){

                this.list.append("<li>"+ term.get('field[brand_name]')+"</li>");

            }, this);

        }
    });

});

这是我的HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
    <title>Bootstrap 101 Template</title>

    <!-- Bootstrap -->
    <link href="css/bootstrap.min.css" rel="stylesheet">
  </head>
  <body>
    <div class="container">
        <h1>Interactive Food Guide</h1>
        <div>
            <input type="text" id="searchBox"> <br/><br/>
        </div>
        <ul id="listing"></ul>
    </div>


    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>

    <!-- Backbone and Underscore -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.2.1/backbone-min.js"></script>
    <!-- apps functionality -->
    <script src="js/app.js"></script>
    <!-- Include all compiled plugins (below), or include individual files as needed -->
    <script src="js/bootstrap.min.js"></script>
  </body>
</html>

我认为这里的主要问题是您忘记了实例化您的应用程序:

new App();

其次,您需要使用正确的结构引用您的数据:

term.get('hits')

As term 是模型,其中包含一个数组 hits

最后,您需要在您的视图中查看您的集合,并在您的视图集合上监听同步:

this.listenTo(this.collection, 'sync', this.render);

我像这样更新了你的 app.js:

$(function(){

var SearchList = Backbone.Collection.extend({
    url: "https://api.nutritionix.com/v1_1/search/taco?results=0%3A20&cal_min=0&cal_max=50000&fields=item_name%2Cbrand_name%2Citem_id%2Cbrand_id&appId=26952a04&appKey=78e2b31849de080049d26dc6cf4f338c",

    initialize: function(){
        this.bind("reset", function(model, options){
        console.log("Inside event");
        console.log(model);
        });
    }

});

// The main view of the application
var App = Backbone.View.extend({

    // Base the view on an existing element
    el: $('.container'),

    initialize: function () {

        this.collection = new SearchList();

        this.collection.fetch({
            success: function (response, xhr) {
                console.log("Inside success");
                console.log(response.toJSON());
            },
            ERROR: function (errorResponse) {
                console.log(errorResponse)
            }
        });

        this.listenTo(this.collection, 'sync', this.render);

        // Cache these selectors
        // this.total = $('#total span');
        this.list = $('#listing');


    },

    render: function(){

        var context = this;
        this.collection.each(function (term) {
            _.each(term.get('hits'), function (item) {
                context.list.append("<li>" + item.fields.brand_name + "</li>");
            });

        }, this);

    }
});
new App();
});

正确的方法不是使用 var context = this; 而是视图中的一个元素。我只是想为您指出正确的方向:-)

我可以看到代码中有一些错误:

    url返回的
  1. JSON是一个对象,你应该在集合中收取的是对象内部的数组"hits"。这个过程的逻辑定义在方法"parse"集合中。

  2. 集合已声明为不可见。当在视图中指示要监听你的集合时,你会遇到问题,因为在视图可以实例化之前调用fetch方法,所以视图在执行fetch时并没有实现

这是您的 code 评论。

$(function(){

var SearchList = Backbone.Collection.extend({
    url: "https://api.nutritionix.com/v1_1/search/taco?results=0%3A20&cal_min=0&cal_max=50000&fields=item_name%2Cbrand_name%2Citem_id%2Cbrand_id&appId=26952a04&appKey=78e2b31849de080049d26dc6cf4f338c",

    initialize: function(){

    },

    //** 1. Function "parse" is a Backbone function to parse the response properly
    parse:function(response){           
        //** return the array inside response, when returning the array
        //** we left to Backone populate this collection
        return response.hits;
    }

});

   // The main view of the application
var App = Backbone.View.extend({

    // Base the view on an existing element
    el: $('.container'),

    initialize: function(){

        //** 2. the view must listen to an object inside in the view
        //** so we create a new instance of SearchList and save it into model var of the view
        this.model = new SearchList();
        this.model.fetch();

        this.listenTo(this.model, 'sync', this.render);

        // Cache these selectors
        // this.total = $('#total span');
        this.list = $('#listing');
    },

    render: function(){
        //** 2. Continue
        var terms = this.model;

        // Calculate the total order amount by agregating
        // the prices of only the checked elements
        terms.each(function(term){

            this.list.append("<li>"+ term.get('fields')["brand_name"]+"</li>");

        }, this);

    }
});

//** Create an instance of the view to start the program
var foo = new App();

});

此致