避免使用Session.set

时间:2013-03-26 00:13:55

标签: meteor

我正在使用meteor-router编写一个简单的流星应用程序。我的问题是路由器知道请求参数,但模板不是。所以我结束了这样的约定:

Meteor.Router.add({'/projects/:id', function(id) {
    Session.set('currentProjectId', id);
    return 'project';
}

Template.project.project = function() {
    return Projects.findOne(Session.get('currentProjectId'));
}

是否有更简洁的方法在模板级别获取当前请求ID参数,以避免所有这些会话变量?

1 个答案:

答案 0 :(得分:5)

会话对象是全局(单一)注册表。有很多理由没有使用它们(只是谷歌“为什么(单线,全局对象,注册表模式)(是|是)坏”。

在Meteor中,情况有点特别。 Session对象是一种非常简单的方法来反应性地存储变量。这是您在应用程序中不使用全局变量的唯一原因。假设你不需要反应性 - 你会把它变成一个全局变量吗?可能不是。

您错误地使用会话从代码中的一个位置获取变量的内容到另一个位置(在另外两个不相关的对象之间是内容的不可见的“神秘桥梁”)。这既不是“流星”方式也不是干净利用(参考上面的搜索结果)。这只是一个简单,肮脏的可能性。

清洁方法

如何避免这种情况:创建自己的反应变量。 Meteor为它提供了所有方法,而且这很容易实现:

(function () {
    var currentProject;
    var currentProjectDependency = new Deps.Dependency();

    Meteor.Router.add({'/projects/:id', function(id) {
        currentProject = id;
        currentProjectDependency.changed();
        return 'project';
    }

    Template.project.project = function() {
        Deps.depend(currentProjectDependency);
        return Projects.findOne(currentProject);
    }
}());

现在我们不使用会话来存储信息,但也具有反应性。此外,我们不会污染全球空间。请注意,使用最新版本,Meteor会自动添加闭包。

此示例可以扩展到更复杂的用例,其中反应性跨越多个对象(例如控制器)。看看我的navigation package是一个更复杂的例子。

使用会话的原因

那么为什么Session会存在呢?有两个原因:

为简单起见。流星努力成为初学者的友好。由于对反应性和架构的理解,我描述的方法有点复杂。大多数项目都小到不关心这个。

但是更大的项目可以使用会话:在页面重新加载时存储信息,你无法恢复其他。在我看来,这是使用会话的唯一原因。会话内容在代码推送的页面重新加载中“持久化”。如果这被认为是坏的呢?不会。因为只有一个对象依赖于会话的内容。请注意,这不适用于您的示例,因为您可以轻松恢复信息。