37 votes

Modèle Backbone.js avec collection

J'ai 2 modèles et une collection. JobSummary est un modèle, JobSummaryList est une collection d' JobSummary articles, et puis j'ai une JobSummarySnapshot modèle qui contient un JobSummaryList:

JobSummary = Backbone.Model.extend({});

JobSummaryList = Backbone.Collection.extend({
    model: JobSummary
});

JobSummarySnapshot = Backbone.Model.extend({
    url: '/JobSummaryList',

    defaults: {
        pageNumber: 1,
        summaryList: new JobSummaryList()
    }
});

Quand je l'appelle fetch sur le JobSummarySnapshot objet, il obtient tout... Sauf lorsque je passe par le biais de l' summaryList collection ils sont tous de type object et pas JobSummary.

Je suppose que cela a du sens, puisque d'autres que l' defaults objet, il ne sait pas que l' summaryList doit être de type JobSummaryList. Je peux passer par chaque élément et de le convertir en JobSummary objet, mais j'espérais qu'il y a un moyen de le faire sans avoir à le faire manuellement.

Voici mon code de test (travail jsfiddle ici):

var returnData = {
    pageNumber: 3,
    summaryList: [
        {
        id: 5,
        name: 'name1'},
    {
        id: 6,
        name: 'name2'}
    ]
}; 

var fakeserver = sinon.fakeServer.create();
fakeserver.respondWith('GET', '/JobSummaryList', [200,
{
    'Content-Type': 'application/json'},
                                JSON.stringify(returnData)]);

var callback = sinon.spy();


var summarySnapshot = new JobSummarySnapshot();
summarySnapshot.bind('change', callback);

summarySnapshot.fetch();
fakeserver.respond();

var theReturnedList = callback.getCall(0).args[0].attributes.summaryList;

_.each(theReturnedList, function(item) {
    console.log('Original Item: ');
    console.log(item instanceof JobSummary); // IS FALSE
    var convertedItem = new JobSummary(item);
    console.log('converted item: ');
    console.log(convertedItem instanceof JobSummary); // IS TRUE
});

Mise à JOUR: Il m'est apparu que je pouvais remplacer la fonction d'analyse et de le mettre de cette façon... j'ai ça maintenant:

JobSummarySnapshot = Backbone.Model.extend({
    url: '/JobSummaryList',

    defaults: {
        pageNumber: 1,
        summaryList: new JobSummaryList()
    },

    parse: function(response) {
        this.set({pageNumber: response.pageNumber});

        var summaryList = new JobSummaryList();
        summaryList.add(response.summaryList);

        this.set({summaryList: summaryList});
    }
});

Cela fonctionne tellement bien. En laissant ouverte la question au cas où quelqu'un a des commentaires....

56voto

shesek Points 2726

Votre parse() fonction ne devrait pas set() quoi que ce soit, ses préférable de simplement retourner les attributs, de la colonne vertébrale prendra soin de le définir. par exemple

parse: function(response) {
    response.summaryList = new JobSummaryList(response.summaryList);
    return response;
}

Tout ce que vous renvoyer à partir de parse() est passé de set().

Pas retourner quelque chose (qui est comme retourner à la undefined) est la même que l'appel à la set(undefined), ce qui pourrait l'empêcher de passer la validation, ou certains autres résultats inattendus si votre coutume validate()/set() méthodes s'attend à obtenir un objet. Si votre validation ou d' set() méthode échoue à cause de cela, l' options.success callback passé de Backbone.Model#fetch() ne sera pas appelé.

Aussi, afin de rendre cela plus générique, de sorte que set()ing à un simple objet à partir d'autres endroits (et pas seulement de la réponse du serveur) des effets aussi, vous souhaiterez peut-être substituer set() à la place:

set: function(attributes, options) {
    if (attributes.summaryList !== undefined && !(attributes.summaryList instanceof JobSummaryList)) {
        attributes.summaryList = new JobSummaryList(attributes.summaryList);
    }
    return Backbone.Model.prototype.set.call(this, attributes, options);
}

Vous pouvez également trouver épine Dorsale-relationnel intéressant - il est beaucoup plus facile de traiter avec des collections/modèles imbriquées à l'intérieur des modèles.

edit j'ai oublié de retour de la méthode set (), le code est maintenant mis à jour

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X