我尝试将google地图(外部加载的脚本)添加到流星应用程序中失败,我注意到有两种问题:
<head></head>
,那么它会被渲染为最后。<head>
中再次插入任何依赖的脚本。 (否则脚本抱怨他们没有看到API blabla ..)<head>
之后其余部分将无效。您需要使用Template.MyTemplate.rendered。 基本上我的问题是:
答案 0 :(得分:7)
我刚刚发布了一个关于氛围(https://atmosphere.meteor.com)的软件包,可能会有所帮助。它被称为session-extras,它定义了一些我用来帮助集成外部脚本的函数。代码在这里:https://github.com/belisarius222/meteor-session-extras
基本思想是异步加载脚本,然后在脚本加载完成后的回调中设置Session变量。我使用session-extras包中的函数来尝试使这个过程更平滑。我有一些函数有3或4个不同的依赖项(脚本和订阅),所以它开始变得毛茸茸......
我想我应该补充一点,然后你可以根据是否存在所有依赖项来有条件地渲染模板。因此,如果你有一个facebook按钮,例如,有帮助器检查Session变量,你可以给它一个“禁用”的css类并显示“加载facebook ...”,直到所有必要的脚本都已加载。
编辑2013年3月14日
在许多情况下,还有一种完全不同的方法:创建自己的包。目前Meteorite (instructions)可以实现这一功能,Meteor本身很快就可以使用该功能。这种方法的一些例子是:
如果您将js文件放在一个包中,它会在您的应用代码之前加载,这通常是包含库的好方法。制作包的另一个好处是包可以相互声明依赖关系,所以如果有问题的脚本是例如jQuery插件,你可以在包的package.js
文件中指定包依赖于jQuery,这将确保正确的加载顺序。
有时它会变得更有趣(在中文诅咒意义上),因为许多外部服务,包括mixpanel和filepicker.io,都有两部分加载过程:1)一个JS片段包含在最后正文,以及2)由该片段异步加载的CDN更大的脚本。 js代码片段通常(但不总是!)在更大的脚本加载之前使一些方法可用,这样您就可以调用其函数而无需设置更多逻辑来确定其负载状态。 Mixpanel这样做,虽然重要的是要记住,来自外部服务的一些JS片段希望你在代码片段的末尾设置API密钥,保证在更大的脚本加载之前;在某些情况下,如果在设置API密钥之前加载脚本,则库将无法正常运行。有关尝试解决方法的示例,请参阅meteor-mixpanel软件包。
可以从CDN自己下载更大的js文件并将其粘贴在您的应用程序中;但是,有充分的理由不这样做: 1)托管代码可能会更改,除非您虔诚地检查它,否则您的代码可能会过时并开始使用旧版本的API 2)这些库通常已经过优化,可以快速加载代码段,不会显着增加页面加载时间。如果您在应用程序中包含较大的JS文件,那么您的服务器必须提供服务,而不是CDN,并且它将在初始页面加载时提供服务。
答案 1 :(得分:2)
听起来您正在通过将其与模板中的HTML链接来加载Javascript文件。有一种更流星的做法:
来自Meteor Docs:
Meteor收集树中的所有JavaScript文件,但不包括 客户端的服务器和公共子目录。它缩小了这一点 捆绑并将其提供给每个新客户。你可以自由使用一个 整个应用程序的JavaScript文件,或创建嵌套树 单独的文件,或介于两者之间的任何内容。
所以考虑到这一点,不要将gmaps.js链接到头部,只需下载未缩小版本的gmaps并将其放入应用程序的树中。
同样来自Meteor Docs:
最好以这样的方式编写应用程序 对文件加载顺序不敏感,例如 使用Meteor.startup,或将加载顺序敏感代码移入 智能包,可以明确控制两个的加载顺序 他们的内容和他们的负载顺序相对于其他包。 但是,有时您的应用程序中的加载顺序依赖性 不可避免的。加载应用程序中的JavaScript和CSS文件 根据这些规则:
加载应用程序根目录下的lib目录中的文件 第一强> [强调添加]
如果序列仍然存在问题,请将js文件放入client/lib
,它将在您编写的所有Javascript之前加载。
答案 2 :(得分:1)
我使用了meteor-external-file-loader和一些异步循环来加载一些脚本,这些脚本将按照你指定的顺序加载javascript(或样式表)。
确保有陨石并添加上面的包&gt;&gt; mrt add external-file-loader
这是我为了使用这个包而编写的函数:
var loadFiles = function(files, callback) {
if (!callback) callback = function() {};
(function step(files, timeout, callback) {
if (!files.length) return callback();
var loader;
var file = files.shift();
var extension = file.split(".").pop();
if (extension === "js")
loader = Meteor.Loader.loadJs(file, function() {}, timeout);
else if (extension === "css") {
Meteor.Loader.loadCss(file);
loader = $.Deferred().resolve();
}
else {
return step(files, timeout, callback);
}
loader.done(function() {
console.log("Loaded: " + file);
step(files, timeout, callback);
}).fail(function() {
console.error("Failed to load: " + file);
step(files, timeout, callback);
});
})(files, 5000, callback);
}
然后使用它,添加一个为模板创建的方法,如下所示:
Template.yourpage.created = function() {
var files = [
"//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js",
"javascripts/bootstrap.min.js"
];
loadFiles(files, function() {
console.log("Scripts loaded!");
});
}
快速编辑:发现将.created方法的功能放在Meteor.startup()中的/ lib文件夹中是个好主意。
Meteor.startup(function() {
if (Meteor.isClient) {
// Load files here.
}
});
警告:很多javascript文件=真正很长的加载时间....不确定这将受到正常的流星javascript文件以及那里的加载顺序的影响。我会确保在用户对网站采取行动之前没有冲突(或者如果存在,则首先加载它们)。