2013-08-07 31 views
11

Tôi muốn sử dụng biến đổi để tạo "trường ảo" trong bộ sưu tập. Tuy nhiên, trường mới mà tôi đang thêm (bên trong hàm biến đổi) đang thêm khá nhiều dữ liệu vào tài liệu được trả về.Meteor Collection Transform: là nó được thực hiện trên máy chủ hoặc trên máy khách? hoặc nó phụ thuộc

Điều này là tốt nếu biến đổi đang diễn ra bên trong ứng dụng khách. Nếu nó được thực hiện trên phía máy chủ, sau đó sẽ có mối quan tâm băng thông.

Vì vậy, tôi tự hỏi nếu biến đổi được thực hiện trên máy chủ, hoặc trên máy khách, hoặc nó phụ thuộc vào cách tôi tìm/lấy tài liệu?

+0

Thay vì tạo ra những lĩnh vực mới trong chuyển đổi chức năng, bạn không thể thêm một chức năng để tài liệu đó sẽ trở lại cùng giá trị? Bằng cách này, bạn có thể nhận được xung quanh vấn đề bạn (nghĩ rằng bạn) có? –

+0

Ồ vâng. Nhưng tôi đã quan tâm nhiều hơn trong việc biết liệu tài liệu được chuyển đổi có thực sự được truyền từ máy chủ đến máy khách hay không. Chỉ cần một chút kỹ thuật. – Dave

+0

Chỉ cần lưu ý rằng hàm chuyển đổi được áp dụng sau khi bạn 'fetch()' tài liệu (hoặc tương đương). 'find()' sẽ trả về con trỏ. Sau khi tìm nạp kết quả, hàm được áp dụng. – Sebastian

Trả lời

23

CẬP NHẬT: Có thể làm một chuyển đổi trên máy chủ.

Bạn có thể có một chuyển đổi trên máy khách như thế này:

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

Meteor bỏ qua transform trên các truy vấn được công bố (từ bên trong Meteor.publish). Khách hàng thấy tài liệu như thể biến đổi không tồn tại.

Nếu bạn muốn sử dụng biến đổi trên máy chủ, bạn có thể làm điều này:

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

Tuyệt vời, cảm ơn bạn đã xem xét 'Meteor.publish'. Bạn trả lời chính xác những gì tôi cần biết. – Dave

+0

@Akshat bạn nói: "Bộ sưu tập được chuyển đổi sẽ không được gửi cho khách hàng", vì vậy tôi có thể kết luận rằng không thể tạo "các trường ảo" và giữ cho khách hàng không biết? – Hamal000

+0

@ Hamal000 bạn có thể sử dụng 'this.added' để tạo các tài liệu ảo hoàn toàn với các trường ảo, nhưng bạn sẽ phải tự quản lý các thay đổi với' this.changed' này. Ví dụ phòng chat trên các tài liệu thiên thạch cho thấy điều này – Akshat

1

Bạn có thể sử dụng chuyển đổi trên cả hai mặt, khi bạn chỉ định một lựa chọn chuyển đến bộ sưu tập hoặc findOne, lấy, vv

chuyển đổi chức năng
Một chức năng chuyển đổi tùy chọn. Tài liệu sẽ được chuyển qua hàm này trước khi được trả về từ tìm nạp hoặc findOne, và trước khi được chuyển tới callbacks of observ, allow và deny.

Nếu bạn cần lấy tài liệu thô từ bộ sưu tập có tùy chọn chuyển đổi.

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

Bạn có thể thêm và sử dụng các chức năng sau:

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(); 
    }); 
} 

sử dụng (server side):

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

Hạn chế: nếu bạn lưu tài liệu đã xuất bản, bạn cũng sẽ lưu các thay đổi đã thêm. Ở đây khách hàng không có đầu mối tài sản "aField" đã được thêm vào trong quá trình xuất bản.

1

Bạn cũng có thể thêm biến đổi trực tiếp trong định nghĩa thu thập. Lưu ý: Như đã đề cập ở trên, điều này có nguy cơ lưu trữ thêm dữ liệu vào bộ sưu tập của bạn khi cập nhật. Đối với các bộ sưu tập chỉ đọc, đây không thực sự là một vấn đề.

Tôi cũng hy vọng điều này sẽ nằm trong thư mục lib được chia sẻ hoặc tương tự, cả máy khách và máy chủ đều thấy định nghĩa này.

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; 

})(); 
Các vấn đề liên quan