2013-08-07 9 views
11

Chcę użyć transformacji, aby "wirtualne pole" z kolekcji. Jednak nowe pole, które dodaję (w ramach funkcji transformacji) dodaje trochę danych do zwróconego dokumentu.Transformacja kolekcji Meteorytów: czy robi się to na serwerze lub na kliencie? lub to zależy

Jest to w porządku, jeśli transformacja odbywa się wewnątrz klienta. Jeśli zostanie to zrobione po stronie serwera, pojawią się obawy związane z przepustowością.

Zastanawiam się, czy transformacja odbywa się na serwerze, czy na kliencie, czy zależy to od tego, jak znajdę/pobierz dokument?

+0

Zamiast tworzenia nowego pola w funkcji transformacji, nie można dodać funkcję do dokumentu, który powróci ta sama wartość? W ten sposób możesz obejść problem, który masz (myślisz)? –

+0

O tak. Ale bardziej interesowało mnie, czy przetransformowany dokument faktycznie przechodzi z serwera na klienta. Tylko odrobina technicznej. – Dave

+0

Należy zauważyć, że funkcja transformacji jest stosowana po 'fetch()' dokumencie (lub jego odpowiedniku). 'find()' zwróci kursor. Po pobraniu wyników funkcja zostanie zastosowana. – Sebastian

Odpowiedz

23

UPDATE: To jest możliwe do zrobienia transformacji na serwerze.

można mieć przekształcić na kliencie tak:

return YourCollection.find({}, {transform: function (doc) { 
    doc.test = true; 
    return true; 
}}); 

Meteor ignoruje transform na pytania, które są publikowane (od wewnątrz Meteor.publish). Klient widzi dokument tak, jakby transformacja nie istniała.

Jeśli chcesz użyć transformacji na serwerze można to zrobić:

YourCollection = new Mongo.Collection("collection_name"); 

Meteor.publish("yourRecordSet", function() { 

    //Transform function 
    var transform = function(doc) { 
    doc.date = new Date(); 
    return doc; 
    } 

    var self = this; 

    var observer = YourCollection.find().observe({ 
     added: function (document) { 
     self.added('collection_name', document._id, transform(document)); 
    }, 
    changed: function (newDocument, oldDocument) { 
     self.changed('collection_name', newDocument._id, transform(newDocument)); 
    }, 
    removed: function (oldDocument) { 
     self.removed('collection_name', oldDocument._id); 
    } 
    }); 

    self.onStop(function() { 
    observer.stop(); 
    }); 

    self.ready(); 

}); 
+0

Świetne, dziękuję za wzięcie pod uwagę 'Meteor.publish'. Odpowiedziałeś dokładnie, co muszę wiedzieć. – Dave

+0

@Aksjomat, o którym mówisz: "Przekształcona kolekcja nie zostanie wysłana do klienta", więc czy mogę stwierdzić, że nie jest możliwe utworzenie "wirtualnych pól" i nieuświadamianie klientów? – Hamal000

+0

@ Hamal000 możesz użyć 'this.added' do tworzenia całkowicie wirtualnych dokumentów z wirtualnymi polami, ale musisz samodzielnie zarządzać zmianami za pomocą' this.changed'. Przykład pokoi rozmów na dokumentach meteorowych pokazuje ten kod – Akshat

1

Można użyć przekształcić po obu stronach, gdy podasz opcję przekształcenia do zbierania lub findOne, przynieś itp

przekształcić funkcji
Opcjonalna funkcja transformacji. Dokumenty będą przekazywane przez tę funkcję, zanim zostaną zwrócone z pobierania lub findOne, a przed przekazaniem do wywołań zwrotnych obserwowania, zezwolenia i odmowy.

Jeśli potrzebujesz surowego dokumentu z kolekcji z opcją transformacji.

myCollection.findOne({},{transform:null}) 
1

Można dodawać i korzystać z następujących funkcji:

Meteor.publishWithTransform = function(publicationName, cursorGetter , transform) 
{ 
    transform = transform || function(o){return o;}; 
    Meteor.publish(publicationName, function() 
    { 
     var cursor = cursorGetter.apply(this, arguments); 
     var collectionName = cursor._cursorDescription.collectionName; 

     var self = this; 

     var observer = cursor.observe({ 
      added: function (document) { 
       self.added(collectionName, document._id, transform(document)); 
      }, 
      changed: function (newDocument, oldDocument) { 
       self.changed(collectionName, newDocument._id, transform(newDocument)); 
      }, 
      removed: function (oldDocument) { 
       self.removed(collectionName, oldDocument._id); 
      } 
     }); 

     self.onStop(function() { 
      observer.stop(); 
     }); 

     self.ready(); 
    }); 
} 

Usage (po stronie serwera):

Meteor.publishWithTransform("publication-name", function() { 
    aCollection.find({}) 
}, function (item) 
{ 
    item.aField = "something"; 
    return item; 
}); 

Wadliwość: jeśli zapiszesz opublikowany dokument, zapiszesz także dodane zmiany. Tutaj klient nie ma pojęcia, że ​​właściwość "aField" została dodana podczas publikacji.

1

Możesz również dodać transformację bezpośrednio również w definicji kolekcji. Uwaga: Jak wspomniano powyżej, wiąże się to z ryzykiem przechowywania dodatkowych danych w kolekcji podczas aktualizacji. W przypadku zbiorów tylko do odczytu nie stanowi to problemu.

Spodziewam się, że będzie to żyć w udostępnionym folderze lib lub podobnym, zarówno klient, jak i serwer, zobaczą tę definicję.

var Assignment; 

// Every record in this collection will now be an 
// instance of the Assignment class. 
this.AssignmentsReport = new Mongo.Collection("assignments", { 
    transform: function(doc) { 
    return new Assignment(doc._id, doc.assignId, doc.masterId); 
    } 
}); 

// Creating a class instance to actually map the new object. 
Assignment = (function() { 
    function Assignment(_id, assignId, masterId) { 
    var assign, ref; 
    this._id = _id; 
    this.assignId = assignId; 
    this.masterId = masterId; 
    this.assign = (ref = Assignments.find({ 
     _id: this.assignId 
    }).fetch()) != null ? ref[0] : void 0; 
    } 

    return Assignment; 

})(); 
Powiązane problemy