我写了一段代码来从文件中获取CSS内容,我想在我的帮助函数中获取这些数据。
服务器端:
Meteor.methods({
'getCSS': function(filename) {
return '<style>' + Assets.getText('css/' + filename) + '</style>';
}
});
css
文件夹位于private
文件夹内,包含多个页面所需的CSS文件。据我所知,服务器端代码可以正常工作。
客户端:
Template.home.helpers({
'css': function() {
var asyncFn = function(fn, cb) {
Meteor.call('getCSS', fn, function(err, res) {
console.log(res); // prints data correctly
cb && cb(null, res);
});
}
var syncFn = Meteor.wrapAsync(asyncFn);
var result = syncFn('home.css');
console.log(result); // undefined
return result;
}
});
在研究了如何使用Meteor.wrapAsync
之后,这是我能提出的最佳解决方案。不确定我错过了什么。我按照this博客的说明进行了操作。
答案 0 :(得分:2)
您不能在客户端上使用Meteor.wrapAsync
,因为在服务器上,同步性的幻觉取决于Fibers,并且客户端上没有这样的并行。
Fibers有效地内联异步函数,以便在等待回调时可以运行其他代码。除此之外,它还有助于消除callback pyramid of doom反模式。但是,它确实使得你的代码更难以推理,因为如果Javascript对象在光纤之间共享,你必须明确考虑你的代码何时可能会产生(自愿预先占用,例如通过进行数据库调用)。
在任何情况下,在客户端上出现类似内容之前可能还需要一段时间 - 正如您所看到的,Fibers是作为节点的C ++包实现的,并且不能简单地使用Javascript完成,因为它实际上是异步函数调用看起来是同步的。
在你的情况下,延迟加载CSS的正确方法(而不是将其包含在Meteor包的其余部分中)只是将它放在public/
文件夹中(或包含在包中)使用{isAsset: true}
)并在需要时使用<head>
标记加载。
答案 1 :(得分:0)
我并不完全明白你在这里想要达到的目标。
从我的角度来看,cas应该从第一次加载加载和编译。不要认为加载CSS是个好主意...你将无法卸载。
如果您在跟踪器计算中(例如,在路由器中,例如在渲染事件上),您可以使用ReactiveMethod包来进行同步调用。它使用跟踪器依赖性来等待响应。
另外,您最终可以设置服务器端路由从私人文件夹中提供CSS文件...
如果您需要,
干杯
答案 2 :(得分:0)
我没有将返回值存储在局部变量中,而是使用了Session。现在它有效!
Template.home.helpers({
'css': function() {
Meteor.call('getCSS', 'home.css', function(err, res) {
Session.set('css', res);
});
return Session.get('css');
}
});