在我的客户端,我显示了用户列表和存储在数据库中的每个用户点的小图表(使用名为sparklines的jQuery插件).
绘制图表是在Template.rendered方法上完成的
// client/main.js
Template.listItem.rendered = function() {
var arr = this.data.userPoints // user points is an array of integers
$(this.find(".chart")).sparkline(arr);
}
Run Code Online (Sandbox Code Playgroud)
现在我在服务器端有一个Meteor方法,定期调用它来更新用户点.
Meteor.methods({
"getUserPoints" : function getUserPoints(id) {
// access some API and fetch the latest user points
}
});
Run Code Online (Sandbox Code Playgroud)
现在,我希望每当调用Meteor方法时,图表都会自动更新.我在模板上有一个方法,并调用此Meteor方法.
Template.listItem.events({
"click a.fetchData": function(e) {
e.preventDefault();
Meteor.call("getUserPoints", this._id);
}
});
Run Code Online (Sandbox Code Playgroud)
如何将此代码转换为"被动"代码?
Kub*_*bek 15
您需要与Tracker一起使用reactive data source(Session,ReactiveVar).
if (Meteor.isClient) {
Template.listItem.events({
"click a.fetchData": function(e) {
e.preventDefault();
var instance = Template.instance();
Meteor.call("getUserPoints", this._id, function(error, result) {
instance.userPoints.set(result)
});
}
});
Template.listItem.created = function() {
this.userPoints = new ReactiveVar([]);
};
Template.listItem.rendered = function() {
var self = this;
Tracker.autorun(function() {
var arr = self.userPoints.get();
$(self.find(".chart")).sparkline(arr);
})
}
}
Run Code Online (Sandbox Code Playgroud)
if (Meteor.isClient) {
Template.listItem.events({
"click a.fetchData": function(e) {
e.preventDefault();
Meteor.call("getUserPoints", this._id, function(error, result) {
Session.set("userPoints", result);
});
}
});
Template.listItem.rendered = function() {
var self = this;
Tracker.autorun(function() {
var arr = Session.get("userPoints");
$(self.find(".chart")).sparkline(arr);
})
}
}
Run Code Online (Sandbox Code Playgroud)
这些实施之间的区别:
ReactiveVar类似于Session变量,但有一些差异:
ReactiveVars没有全局名称,例如Session.get("foo")中的"foo".相反,它们可以在本地创建和使用,例如附加到模板实例,如:this.foo.get().
ReactiveVars不会通过热代码推送自动迁移,而会话状态是.
ReactiveVars可以包含任何值,而Session变量仅限于JSON或EJSON.
Deps已弃用,但仍可使用.
最容易扩展的解决方案是将数据存储在本地集合中 - 通过传递一个空名称,该集合将是本地和会话,因此您可以将所需内容放入其中并仍然可以实现反应的所有好处.如果将结果getUserPoints插入到此集合中,则只需编写一个帮助程序即可为每个用户获取适当的值,它将自动更新.
userData = new Meteor.Collection(null);
// whenever you need to call "getUserPoints" use:
Meteor.call("getUserPoints", this._id, function(err, res) {
userData.upsert({userId: this._id}, {$set: {userId: this._id, points: res}});
});
Template.listItem.helpers({
userPoints: function() {
var pointsDoc = userData.findOne({userId: this._id});
return pointsDoc && pointsDoc.points;
}
});
Run Code Online (Sandbox Code Playgroud)
还有一种使用Tracker软件包(以前称为Deps)的替代方法,这种方法可以在这里快速实现,但可以随意扩展.从本质上讲,您可以设置一个新Tracker.Dependency的跟踪用户点的更改:
var pointsDep = new Tracker.Dependency();
// whenever you call "getUserPoints":
Meteor.call("getUserPoints", this._id, function(err, res) {
...
pointsDep.changed();
});
Run Code Online (Sandbox Code Playgroud)
然后只需在listItem模板中添加一个虚拟帮助器(即一个不按设计返回任何内容的帮助器):
<template name="listItem">
...
{{pointsCheck}}
</template>
Template.listItem.helpers({
pointsCheck: function() {
pointsDep.depend();
}
});
Run Code Online (Sandbox Code Playgroud)
虽然这不会返回任何内容,但它会强制模板在pointsDep.changed()被调用时重新呈现(这将是新用户点数据被接收时).
| 归档时间: |
|
| 查看次数: |
3833 次 |
| 最近记录: |