Meteor 中的全局变量
Posted
技术标签:
【中文标题】Meteor 中的全局变量【英文标题】:Global variables in Meteor 【发布时间】:2015-02-15 00:42:25 【问题描述】:我有
var Schemas = ;
Meteor.isClient && Template.registerHelper("Schemas", Schemas);
Schemas.Person = new SimpleSchema(
fullName:
type: String,
index: 1,
optional: true,
,
email:
type: String,
optional: true
,
address:
type: String,
optional: true
,
isActive:
type: Boolean,
,
age:
type: Number,
optional: true
);
在一个文件中
var Collections = ;
Meteor.isClient && Template.registerHelper("Collections", Collections);
Persons = Collections.Persons = new Mongo.Collection("Persons");
Persons.attachSchema(Schemas.Person);
在另一个文件中。
我收到错误 ReferenceError: Schemas is not defined
。很明显,我必须在我的 collections.js
文件中定义 Schemas
而不是将它们分开。但是 Meteor 如何处理单独文件中的代码?我可以访问一些对象和变量,而另一些则无法访问。
【问题讨论】:
Schemas
是全局变量吗?您是否使用require
加载它?也许您需要向我们展示更多代码,因为编写代码时应该没有问题
How can I access constants in the lib/constants.js file in Meteor?的可能重复
【参考方案1】:
当您以经典的 javascript 方式定义变量时:
var someVar = 'someValue';
在 .js
文件的根目录中,Meteor 使用 IIFE 将其范围限定为文件。
如果你想定义一个全局变量,干脆不要写var
,给:
someVar = 'someValue';
默认情况下,这将在您的所有应用程序中定义一个变量,尽管您可以通过在specific recognized folder(例如client
或server
文件夹)中编写该声明来限制它。
但是,这个变量不会首先被绝对定义。它将在 Meteor 运行定义它的实际代码时定义。因此,这可能不是最佳实践,因为您将难以处理加载顺序,并且它将使您的代码取决于 Meteor loads files: 您将文件放入哪个文件夹,文件的名称...您的如果你稍微接触一下你的架构,代码很容易出现混乱的错误。
正如我在another closely related post 中建议的,你应该直接去买一个包!
【讨论】:
我尝试在 lib 目录中定义我的全局变量,但包肯定更健壮 我想补充一点,这真的很酷,因为您可以在 /client 中有一个 constants.js 文件,在 /server 目录中还有另一个。如果你想在两者之间共享一个常量文件,你可以在 /lib/constants 中创建它。 这不是 Meteor 问题。请参阅下面的 ReferenceError。【参考方案2】:Meteor 中使用 var
关键字声明的变量的作用域仅限于声明它们的文件。
如果你想创建一个全局变量这样做
Schemas =
【讨论】:
我不确定我对此有何感想...是否没有 ES6/webpack 风格的方法可以从另一个文件导入变量以避免全局变量?【参考方案3】:ReferenceError 是节点错误。 Meteor 是一个基于 Node.js 的框架。
Node 具有全局范围(又名 Node 的 global
变量)。 如果您尝试访问未定义的全局变量,Node(不是 Meteor)会抛出此错误。
浏览器还有一个名为 window
的全局作用域,并且在访问未定义的变量时不会抛出 ReferenceErrors。
这是我喜欢为类添加功能的一种模式(它非常像 Meteor):
/lib/Helpers.js <-- Helpers for everyone (node+browser)
/server/Helpers.js <-- Server helpers (node)
/client/Helpers.js <-- Client helpers (browser)
考虑这些实现:
// /lib/Helpers.js
Helpers = /* functions */; // Assigned to window.Helpers and global.Helpers
// /server/Helpers.js
Helpers = _.extend(Helpers, /*more functions*/
// /client/Helpers.js
Helpers = _.extend(Helpers, /*more functions*/
这是一个简单的例子。如果我不想担心加载顺序怎么办?为什么不在 /lib/Helpers.js 中使用 _.extend()?
// /lib/Helpers.js
// Helpers = /* functions */; // Overwrites...
Helpers = _.extend(Helpers, /* functions */); // ReferenceError
因为如果未定义 Helpers,您将从 Node 收到 ReferenceError - 特别是用作参数的“Helpers”。 (Node 知道将 Helpers 分配为 global.Helpers)。
这里有两种“修复”此问题的方法:
1) 为某事分配助手
// /lib/Helpers.js
// Helpers = Helpers || // would be another ReferenceError
if (typeof Helpers === 'undefined') Helpers = ;
Helpers = _.extend(Helpers, /* functions */);
2) 使用来自全局的帮助器
// /lib/Helpers.js
Helpers = _.extend(global.Helpers, /* functions */); // works in node, but...
两者都很糟糕。
1) 的语法很糟糕。 2)在节点中工作,但在浏览器中没有全局。所以它没有达到它的目的。
所以我放弃了第一次在 lib 中覆盖它,如果有任何内容被覆盖,则查找运行时错误。
如果你有一个方便的跨浏览器语法,请评论:-) var 某事 = 某事 || something.blah = foo;
这是其他一些JS shorthand tips。
【讨论】:
请注意,第三段代码必须添加在每个需要使用全局变量的文件的开头,以供每个变量使用。 你能解释一下你为什么提到 ES6 以及这与这个问题有什么关系吗? @Fletch 嗯...实际上没有。所以我删除了它。出于某种原因,我认为 ES6 模块将有助于清理全局命名空间,但我找不到任何关于它的信息:-/【参考方案4】:会话变量是全局变量,可以在不同的文件/函数中轻松访问。 Session.setPersistent 用于在所有文件中持久设置变量名称。当他们的应用程序太大时,可能会限制使用会话变量,因为它们不会被删除(因此可能存在内存泄漏),并且可能会在控制台中出现错误(如果未定义左右)。文档链接:https://docs.meteor.com/api/session.html
【讨论】:
也可以使用 delete Session.keys[sessionName] 删除会话变量。链接:***.com/questions/10743703/…以上是关于Meteor 中的全局变量的主要内容,如果未能解决你的问题,请参考以下文章