2017-07-03 2 views
0

Je travaille à travers un tutoriel, la construction d'une petite bibliothèque DB Express et Mongoose. Dans le tutoriel, chaque livre peut avoir plusieurs statuts, et seulement une de ces valeurs. C'est un Enum. Je traitais cela en mettant un tableau de valeurs dans le schéma BookInstance:Impossible d'accéder à des variables de schéma dans Mongoose par la méthode statique

var the_statuses = ['Available', 'Maintenance', 'Loaned', 'Reserved']; 

qui fonctionne très bien quand j'ai une instance - j'utiliser une méthode virtuelle pour récupérer ces valeurs

BookInstanceSchema 
    .virtual('statuses') 
    .get(function() { 
     return the_statuses; 
    }); 

quand je , comme dit, ont déjà une instance.

Et lors de la création du schéma j'accéder à ma variable locale, ainsi, une variable locale:

var BookInstanceSchema = Schema({ 
    book: { type: Schema.ObjectId, ref: 'Book', required: true }, //reference to the associated book 
    imprint: {type: String, required: true}, 
    status: {type: String, required: true, enum: the_statuses, default: 'Maintenance'}, 
    due_back: {type: Date, default: Date.now}, 
}); 

Mais si je veux simplement les valeurs enum directement à partir du schéma, mais de en dehors la schéma? Autrement dit, si je veux créer, dans ce cas, une instance de BookInstance, et offrir à l'utilisateur un choix de statuts dans un menu de sélection, je ne vais pas avoir accès à une instance encore (à moins que je bidouille et simplement créer un pour saisir les valeurs enum).

J'ai essayé de faire une fonction statique

BookInstanceSchema.statics.getStatuses = function() { 
    return this.the_statuses; 
}; 

Mais il ne semble pas fonctionner.

Quelle est la meilleure façon de faire ce que je suis en train de faire? Existe-t-il une "méthode virtuelle statique" dans Mongoose?

Répondre

1

Il a été un peu depuis que je l'ai utilisé MongoDB (et Mongoose, évidemment), mais static méthodes n'ont pas accès aux instances. Ainsi, vous ne devriez vraiment pas utiliser this dans une méthode statique. En outre, il n'apparaît pas qu'une instance de BookInstanceSchema a une propriété the_statuses (juste le statuses virtuel). A en juger par votre code, il semblerait que vous ayez accès à la variable the_statuses dans votre définition BookInstanceSchema. Alors, pourquoi ne pas l'utiliser directement?

BookInstanceSchema.statics.getStatuses = function() { 
    return the_statuses; 
}; 

// Use like 
BookInstanceSchema.getStatuses(); 

EDIT:

Pour plus d'informations générales sur this en JavaScript, consultez this post et MDN docs. En bref, son comportement change en mode « strict », et il peut être manipulé par les méthodes de la classe Fonction .call et .apply, pour ne citer que quelques-uns des bizarreries.

Vous auriez raison de supposer que this ferait référence à l'objet avec lequel une méthode donnée a été appelée, car il s'agit d'un comportement par défaut. Dans notre cas, cet objet serait BookInstanceSchema.statics. Mais, il y a le cas que Mongoose appelle une méthode sous statics dans un contexte différent (je suppose), comme BookInstanceSchema, mais il n'appelle certainement pas du contexte d'une instance, c'est le contexte que les méthodes sur BookInstanceSchema.methods seraient appelées Il faut noter que ceci est complètement non-standard. Mongoose imite essentiellement les concepts OOP comme les méthodes de classe, et les méthodes d'instance (Schema.statics et Schema.methods, respectivement). Dans le cas de Mongoose, je ne suis pas sûr quel objet this fait référence aux méthodes sur Schema.statics, mais il fait certainement référence à l'objet d'instance sur Schema.methods.À mesure que la syntaxe «classe» vieillit (présentée dans ES2015), d'autres bibliothèques accepteront probablement un moyen plus «standard» de définir les méthodes de classe et les méthodes d'instance (Sequelize travaille sur cette question dans leur prochaine version). De plus, les concepts de POO, comme les méthodes de classe et les méthodes d'instance, sont réalisables dans JS, même si c'est un peu différent. Si cela vous intéresse, this article vous expliquera comment cela fonctionne dans Vanilla JS, ainsi que d'excellents exemples de la nouvelle syntaxe de la classe qui contraste avec l'ancienne syntaxe fonction-prototype.

+0

A travaillé parfaitement. Bien que j'ai programmé longtemps, ça a été dans d'autres langues et le "ça" de Javascript me lance parfois. Dans ce contexte, il faut être dans une instance pour se référer à 'ceci'? Si je comprends bien, 'ceci' fait référence à la structure objet/code à partir de laquelle une fonction est appelée - mais si vous appelez une méthode statique dans Mongoose, cela s'appelle _from_ quelque chose? Je pense que je suis peut-être en train de mixer et de mettre en correspondance la POO - ce à quoi je suis habitué - et le monde Javascript, mais je tiens à comprendre pourquoi votre solution a fonctionné. Mais de toute façon, merci! – Cerulean

+0

Heureux que cela a aidé. Ouais, 'ceci 'est très bizarre dans JS, encore plus dans le contexte de Mongoose. Éditera la réponse avec quelques détails. – Nindaff