简体   繁体   中英

How can I output the JSON?

<!DOCTYPE HTML>
<html>
<head>
<title></title>
    <link href="/bundles/hoaxpartner/css/style.css" type="text/css" rel="stylesheet" />
</head>
    <body>

    <div id="header">Backbone</div>
    <div id="sidebar"></div>
    <div id="content"></div>

    <script type="text/template" id="tpl-user-list-item">
        <a href='#users/<%= id %>'><%= name %></a>
    </script>

    <script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.1/jquery.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore-min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.0.0/backbone-min.js"></script>

    <script>

        window.User = Backbone.Model.extend();

        window.UserCollection = Backbone.Collection.extend({
            model: User,
            url: "/app_dev.php/api/users/1/",
            parse : function(resp) {
                /*
                $.each(resp.users, function(key1, value1) {
                    resp.users[key1] = $.map(value1, function(value2, key2) { 
                        return [value2];
                    });
                });
                */
                return resp.users;
            },
        });

        // Views
        window.UserListView = Backbone.View.extend({

            tagName:'ul',

            initialize:function () {
                this.model.bind("reset", this.render, this);
            },

            render:function (eventName) {
                _.each(this.model.models, function (user) {
                    $(this.el).append(new UserListItemView({model:user}).render().el);
                }, this);
                return this;
            }

        });

        window.UserListItemView = Backbone.View.extend({

            tagName:"li",

            template:_.template($('#tpl-user-list-item').html()),

            render:function (eventName) {
                $(this.el).html(this.template(this.model.toJSON()));
                return this;
            }

        });

        // Router
        var AppRouter = Backbone.Router.extend({

            routes:{
                "":"list"
            },

            list:function () {
                this.userList = new UserCollection();
                this.userListView = new UserListView({model:this.userList});
                this.userList.fetch();
                $('#sidebar').html(this.userListView.render().el);
            }

        });

        $(function() {
            var app = new AppRouter();
            Backbone.history.start();
        });

    </script>

</body>
</html>

/app_dev.php/api/users/1 call output:

{
  "users": [
    {
      "userid": "Jf9CEy70",
      "password": "g5JY9OB2",
      "status_id": 1,
      "created": "2014-01-13 18:33:25"
    },
    {
      "userid": "8LZVQX6b",
      "password": "QFzO92tM",
      "status_id": 1,
      "created": "2014-01-13 18:35:00"
    },
    {
      "userid": "cItWduq9",
      "password": "SuzcWisl",
      "status_id": 0,
      "created": "2014-01-13 18:35:21"
    }
  ]
}

The data is received from "/app_dev.php/api/users/1" API, but I'm stuck on displaying it.

1- Try to add this function to your collection :

parse : function(resp) {
    return resp.users;
}

Because your collection is waiting an array of models, but it gets an object.

2- Change this ligne this.collection.on('change', this.render, this); by this one this.collection.on('reset', this.render, this); , because when the collection receive the data from the server it trigger a reset event (it's the Model that trigger change )

3- Add this line

this.collection = new App.Collections.Models();

before this line

view = new App.Views.ModelsIndex({'collection': this.collection});

Because you are using this.collection without initializing it.

4- Change the tagName in your App.Views.ModelsIndex to el and give it the div where you want your template to be rendered ( '#someEl' )

UPDATE

Your new problem is the template, you have some errors in it (userId instead of id, there is no name in your json), here is a working one :

<script type="text/template" id="tpl-user-list-item">
    <a href = '#users/<%= userid %>' ><%= created %></a>
</script>

Because this.collection.fetch(); is asynchronous, so if you call it in initialize and then call index immediately, the collection at this time is not "fetched" yet. You should change your code to properly handle asynchronous calls

Another thing is that you are listening to change event which is applied when there are changes for each model in the collection, you should listen to reset event (if you want to reset the model after fetching) or sync (if I remember correctly)

Another event that might be useful is request which will be fired as soon as the ajax request is sent

Updated: So in this case, you can change

this.collection.on('change', this.render, this);

to

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

And move

this.collection.fetch();

To after

view = new App.Views.ModelsIndex({'collection' : this.collection});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM