5

我尝试将谷歌地图(外部加载的脚本)添加到流星应用程序但未成功,我注意到有两种问题:

  1. 如果我做简单的事情并将主要的 API 脚本添加到我的<head></head>中,那么它会在最后呈现。
  2. 发生这种情况时,我必须在我的模板中再次插入任何依赖<head>于 API 的脚本 - 在主 API 脚本之后。(否则脚本会抱怨他们看不到 API blabla ..)
  3. 然后是实际调用函数的时候了——现在把它放在里面<head>是行不通的。您需要使用 Template.MyTemplate.rendered。

基本上我的问题是:

  • 处理这些事情的最干净的方法是什么?
  • 我可以使用其他一些变量/方法来确保在我的 HTML 中首先调用我的 Google 主 API 文件吗?
4

3 回答 3

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,有一个 2 部分加载过程:1)在正文末尾包含一个 JS 片段,和 2) 由该片段从 CDN 异步加载的更大脚本。js 片段通常(但并非总是如此!)在更大的脚本加载之前使一些方法可用,这样您就可以调用其函数而无需设置更多逻辑来确定其加载状态。Mixpanel 会这样做,尽管重要的是要记住,来自外部服务的一些 JS 片段希望您在片段末尾设置 API 密钥,保证在更大的脚本加载之前;在某些情况下,如果脚本在设置 API 密钥之前加载,库将无法正常运行。

可以简单地自己从 CDN 下载更大的 js 文件并将其粘贴到您的应用程序中;但是,有充分的理由不这样做:1)托管代码可能会更改,除非您认真检查,否则您的代码可能会过时并开始使用旧版本的 API 2)这些库通常已经优化以快速加载代码段,不会显着增加页面加载时间。如果您在应用程序中包含较大的 JS 文件,那么您的服务器必须提供它,而不是 CDN,它将在初始页面加载时提供它。

于 2013-03-13T05:46:04.607 回答
2

听起来您正在通过将 Javascript 文件与模板中的 HTML 链接来加载它。还有一种更 Meteor 的方式来做到这一点:

来自流星文档

Meteor 会收集树中的所有 JavaScript 文件,但客户端的服务器和公共子目录除外。它会缩小这个捆绑包并将其提供给每个新客户。您可以自由地为整个应用程序使用单个 JavaScript 文件,或创建单独文件的嵌套树,或介于两者之间的任何内容。

所以考虑到这一点,不要将 gmaps.js 链接到 head 中,只需下载未缩小版本的 gmaps 并将其放入应用程序的树中。

同样来自 Meteor Docs:

最好以对文件加载顺序不敏感的方式编写应用程序,例如使用 Meteor.startup 或将加载顺序敏感代码移动到智能包中,这样可以显式控制加载它们的内容顺序和相对于其他包的加载顺序。然而,有时应用程序中的加载顺序依赖性是不可避免的。应用程序中的 JavaScript 和 CSS 文件根据以下规则加载:

首先加载应用程序根目录下的 lib 目录中的文件。 [重点补充]

如果序列仍然存在问题,请将 js 文件放入client/lib其中,它将在您编写的所有 Javascript 之前加载。

于 2013-03-12T23:55:41.497 回答
1

我使用了meteor-external-file-loader 和一些异步循环来加载一些脚本,这些脚本将按照您指定的顺序加载javascript(或样式表)。

确保有陨石并添加上面的包>> 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 文件以及那里的加载顺序会如何影响它。我只是确保在用户在网站上采取行动之前没有冲突(或者如果有,他们首先被加载)。

于 2013-11-27T00:19:50.777 回答