2013-08-14 11 views
16

Ho il seguente schema di documento:Aggiunta di variabili "virtuali" a uno schema di mangusta?

var pageSchema = new Schema({ 
     name: String 
    , desc: String 
    , url: String 
}) 

Ora, nella mia domanda mi piacerebbe avere anche la sorgente html della pagina all'interno dell'oggetto, ma io non voglio memorizzarlo nella db.

Devo creare un oggetto avanzato "locale" che abbia un riferimento al documento db?

function Page (docModel, html) { 
    this._docModel = docModel 
    this._html = html 
} 

C'è un modo per utilizzare direttamente il modello di documento aggiungendo un campo "virtuale"?

+0

Perché vuoi averlo nell'oggetto ma non memorizzarlo? –

+0

Perché non ho bisogno che sia persistente: se riavvio il mio server e ricarico gli oggetti dal database, anche quell'html dovrebbe essere aggiornato (proviene da un processo esterno). Potrei stoccarlo, ma sarebbe uno spazio inutile. Poiché in Mongoose ci sono metodi virtuali, sarebbe stato bello avere anche delle variabili virtuali. – fusio

+1

Puoi semplicemente impostare [damn enter] una proprietà sull'oggetto come 'document.prop = html'. Non penso che il metodo oi virtual consentiranno effettivamente di recuperare i dati "locali" se si recupera nuovamente l'oggetto dal db, anche se non si riavvia. –

risposta

32

Questo è perfettamente possibile in mangusta.
Controllare questo esempio, tratto dal loro documentazione:

var personSchema = new Schema({ 
    name: { 
    first: String, 
    last: String 
    } 
}); 

personSchema.virtual('name.full').get(function() { 
    return this.name.first + ' ' + this.name.last; 
}); 
console.log('%s is insane', bad.name.full); // Walter White is insane 

Nell'esempio precedente, la proprietà non avrebbe un setter. Per avere un setter per questo virtuale, fare questo:

personSchema.virtual('name.full').get(function() { 
    return this.name.full; 
}).set(function(name) { 
    var split = name.split(' '); 
    this.name.first = split[0]; 
    this.name.last = split[1]; 
}); 

Documentation

+2

Sì, ma non stanno aggiungendo nuovi campi .. Stanno usando quelli esistenti. – fusio

+1

E qual è il problema? Puoi anche usare setter. – gustavohenke

+0

oh, capisco. vuoi dire che dovrei 'this.newfield =' all'interno del virtuale 'set'. – fusio

11

Non ho effettivamente testato questo, ma l'idea sembra degna:

//model 
var pageSchema = new Schema({ 
     name: String 
    , desc: String 
    , url: String 
}) 

pageSchema.virtual('html') 
    .get(function(){ 
    var url = this.url 

    function get(url) { 
     return new (require('httpclient').HttpClient)({ 
     method: 'GET', 
      url: url 
     }).finish().body.read().decodeToString(); 
    } 

    return get(url); 
    }); 


    //controller 
    var page = new Page({ 
    name: "Google" 
    , desc: "Search engine" 
    , url: "http://google.com" 
    }); 

    var html = page.html; 

Fondamentalmente impostare un attributo virtuale chiamato html che richiede al corpo l'attributo url e lo restituisce.

Assicurarsi di abilitare l'output degli attributi virtuali per toJSON se si utilizza Express e res.send(page).

pageSchema.set('toJSON', { 
    virtuals: true 
}); 
12

proprietà del documento che iniziano con __ non vengono mantenute al db, così si potrebbe creare una proprietà virtuale e hanno il getter e l'uso setter this.__html

pageSchema.virtual('html').get(function() { 
    return this.__html; 
}).set(function (html) { 
    this.__html = html; 
}); 

ma questo è un po 'di hack con un avvertimento: questa funzionalità non è documentata quindi non esiste un elenco di proprietà interne che iniziano con __ quindi c'è la possibilità, anche se improbabile, che in futuro l'implementazione interna possa iniziare ad usare una var chiamata __html

https://github.com/Automattic/mongoose/issues/2642

Problemi correlati