我在Javascript方面没有经验,但我已经阅读了大量有关Meteor反应性的文章,但仍然无法弄清楚为什么它在我的情况下不起作用。
当添加新产品时,我希望重新计算总成本并在totalCost帮助器中使用它,这样它几乎可以在浏览器中实时显示。
有人可以看看我的代码并试图找出一些逻辑错误吗?除了反应性之外的所有东西都在我的电脑上运行。
我在/models/Product.js
中有这个方法:
Meteor.methods({
totalProductCost: function() {
var pipeline = [
{$match: {owner: Meteor.userId()}},
{$group: {_id: null, cost: {$sum: "$cost"}}}
];
var data = Products.aggregate(pipeline)["0"].cost;
return (data === undefined) ? 0 : data;
}
});
然后我在客户端文件夹中有layout.js:
if (Meteor.isClient) {
var handle = Meteor.subscribe("Products", Meteor.userId());
ProductManager = {
_productItems: null,
_dep: new Tracker.Dependency(),
getProducts: function () {
this._dep.depend();
return this._productItems;
},
setProducts: function (value) {
if (value !== this._productItems) {
this._productItems = value;
this._dep.changed();
}
},
getTotalCost: function () {
return ReactiveMethod.call('totalProductCost');
}
}
// TRACKER
Tracker.autorun(function () {
if (handle.ready()) {
ProductManager.setProducts(Products.find().fetch());
}
});
// HELPERS
Template.boxOverview.helpers({
"totalCost" : function () {
return ProductManager.getTotalCost();
},
});
}
答案 0 :(得分:0)
您似乎在方法中使用了collection.aggregate
。如果需要反应性,则需要使用发布而不是方法(或者每次要刷新时都需要调用该方法)。但是,如果您在出版物中使用聚合(我假设为you use a package for it),您也会失去反应性。
我建议您使用没有aggregate
功能的出版物。您可以通过创建新字段并将其添加到光标来计算产品成本。一旦你这样做,如果你想保持反应性,就必须使用cursor.observeChanges()
或cursor.observe()
。
看一下这个例子:
var self = this;
// Modify the document we are sending to the client.
function filter(doc) {
var length = doc.item.length;
// White list the fields you want to publish.
var docToPublish = _.pick(doc, [
'someOtherField'
]);
// Add your custom fields.
docToPublish.itemLength = length;
return docToPublish;
}
var handle = myCollection.find({}, {fields: {item:1, someOtherField:1}})
// Use observe since it gives us the the old and new document when something is changing.
// If this becomes a performance issue then consider using observeChanges,
// but its usually a lot simpler to use observe in cases like this.
.observe({
added: function(doc) {
self.added("myCollection", doc._id, filter(doc));
},
changed: function(newDocument, oldDocument)
// When the item count is changing, send update to client.
if (newDocument.item.length !== oldDocument.item.length)
self.changed("myCollection", newDocument._id, filter(newDocument));
},
removed: function(doc) {
self.removed("myCollection", doc._id);
});
self.ready();
self.onStop(function () {
handle.stop();
});
这取自here。