Backbone - not parse each model in collection afte

2020-06-16 03:42发布

问题:

How to prevent parse function for model in collection fetching?

    $(function() {
    var Task = Backbone.Model.extend({
        url : function() {
                return this.urlRoot + this.id;
        },
        urlRoot: 'index.php?c=light&a=list_tasks_bb&ajax=true&task=',
        parse: function (response, options) {
            console.log(options);
            console.log(response);
            return response;
        }
    });

    var TaskList = Backbone.Collection.extend({
        model: Task,
        url: 'index.php?c=light&a=list_tasks_bb&ajax=true',

        initialize: function () {

        },
        parse: function (response, options) {
            return response.tasks;
        }
    });

    var Light = Backbone.Router.extend({
        el: $('#light'),
        routes: {
            "tasks/:id": "taskAction",
            "*page": "defaultAction",
        },

        initialize: function () {
            _this = this;
            this.tasks = new TaskList();
            this.users = new UserList();
        },

        taskAction: function(id) {
            this.task = new Task({id: id});
            $.when (
                this.task.fetch()
            ).then(function(zzz) {
                new TaskView({model: _this.task}).render();
            });
        },
        defaultAction: function(page) {
            $.when (
                this.tasks.fetch(),
                this.users.fetch()
            ).then (function() {
                new TaskListView({collection: _this.tasks}).render();
            });
        }
    });
});

I have one model and one collection which I get through ajax fetch. I have no opportunity to change backend, so the json structure of tasks list is:

"contents": {},
"current": false,
"errorCode": 0,
"errorMessage": "",
"u": 4,
"tasks": [{
    "id": "12250",
    "t": "ZZZ",
    "cid": "24",
    "c": "2013-08-22 11:36:32",
    "dd": "02.09.2013",
    "sd": "02.09.2013",
    "pr": "300",
    "pid": "0",
    "atid": "1:4",
    "s": 0,
    "dl": ""
}, {
    "id": "12307",
    "t": "ZZZ",
    "cid": "42",
    "c": "2013-08-28 11:14:44",
    "dd": "05.09.2013",
    "sd": "28.08.2013",
    "pr": "200",
    "pid": "0",
    "atid": "1:4",
    "s": 0,
    "dl": ""
}, {
    "id": "12326",
    "t": "ZZZ",
    "cid": "2",
    "c": "2013-08-29 09:55:34",
    "dd": "31.08.2013",
    "sd": "29.08.2013",
    "pr": "200",
    "pid": "0",
    "atid": "1:4",
    "s": 0,
    "dl": ""
}],
"events": []

This is the reason why I'm using parse for collection. In this step everything is fine. JSON structure for single task is:

"contents": {},
"current": false,
"errorCode": 0,
"errorMessage": "",
"u": 4,
"tasks": [{
    "id": "12250",
    "t": "ZZZZ",
    "cid": "24",
    "c": "2013-08-22 11:36:32",
    "dd": "02.09.2013",
    "sd": "02.09.2013",
    "pr": "300",
    "pid": "0",
    "atid": "1:4",
    "text": "XXXXX",
    "s": 0,
    "dl": ""
}],
"comments": [{
    "id": "48178",
    "text": "CCCC",
    "cid": "4",
    "con": "23.08.2013"
}],
"events": []

So i need parse again for fetch single task after "task.fetch()". After I added parse function in model it working fine until I started fetch collection, because after collection parse I already have correct model data, but model parse callback for each model again.

Do I have correct way to fix this or better will be try to change backend?

PS Sure, I can do something like this:

  if(response.tasks) {
    return response.tasks[0];
  } else {
    return response;
  }

But I think it's not correct solution.

回答1:

When creating models for insertion in a collection, Backbone passes the future collection as an option to the model constructor which in turns forwards this option to parse. You could check this property and abort the parsing as needed:

var Task  = Backbone.Model.extend({
    parse : function(response, options){
        if (options.collection) return response;
        return response.tasks[0];
    }
});
var TaskList = Backbone.Collection.extend({
    model: Task,
    parse : function(response){
        return response.tasks;
    }
});

And a demo http://jsfiddle.net/nikoshr/dfMgR/