你何时应该使用Session和ReactiveVar?我使用Session变量作为组件之间的通信媒介.我们来看看Stackoverflow.
我标记了三个假设的组成部分.我们来看看filters组件.如果单击,Tags则Main组件将根据您最喜欢的标签显示其问题.为此,我将Session.set("Main/showTags", true)在Tags单击按钮时进行设置.在Main组件中,我将有一个如下的辅助函数:
Template.Main.helpers({
posts: function() {
var isTags = Session.get("Main/showTags");
var isQuestions = Session.get("Main/showQuestions");
...
if (isTags) {
return Posts.find().sort({tags: 1}) // or something along the lines
} else if (isQuestions) ...
}
});
Run Code Online (Sandbox Code Playgroud)
这在大多数情况下运作良好,但我从许多地方看到我应该避免使用Session和使用ReactiveVar.但如果我ReactiveVar到处使用,那么我需要对所有模板实例的引用.我希望它在直接父模板和子模板之间运行良好(例如,在主要组件内部,可能会有VoteAnswerViewsButtonTemplate),但是ReactiveVar当你想要独立组件相互通信时,你会怎么做?
这是我的最后一个问题.如何正确使用Session和ReactiveVar保持组件的范围并使它们彼此通信?另外,如果我使用Session现在的方式,我是否不必要地污染全局命名空间?
相关文件:
Bil*_*net 11
据我所知,没有与Session变量相关的内置功能可以将它们与常规的反应式字典全局变量(如@Kyll所述)区分开来,例如,您可以在client.js文件中声明这些变量.唯一的区别是Session必要的可访问应用范围的"限制".
当我在较小的范围内使用反应字典或反应变量时,我很高兴利用这种差异.我认为我有三种范围:
1 - 全球范围.例如,当前的UI语言,UI皮肤.我用Session它.简单的全局数据,而不是那种可能与其他任何东西混淆的数据.
2 - 模板集群.比方说,我创建一个页面来生成和定制我的应用程序中的pdf.我不会在其他地方重用任何组件.我的群集是一个包含三个文件的文件夹,让我们调用它们pdfgenerator.html,pdfgenerator.js然后pdfgenerator_controller.js.
我用它pdfgenerator_controller.js来扩展具有所有细节的路线.
在pdfgenerator.js文件中,我有几个模板,我都在集群中使用.在文件的开头,我创建了一个反应式字典pageSession(类似于反应变量),我在我的所有集群中使用它.它允许我在所有组件之间传递数据.
3 - 本地范围.无论是单个模板还是可重用组件,它都可以单独工作.我也不会将Session vars用于那些.我不想过度拥挤这个Session名字空间.我所做的是将我在实例化过程中运行它所需的每个数据传递给我的模板.
它可能来自Spacebars:
{{> mySingleTemplate data=myData}}
Run Code Online (Sandbox Code Playgroud)
或使用Javascript:
Blaze.renderWithData(Template.mySingleTemplate , myData, self.firstNode);
Run Code Online (Sandbox Code Playgroud)
在本地范围的情况下,我还使用a reactive dictionary或reactive vars只是处理单个模板中发生的反应.在这种情况下,我尝试避免需要将数据反应性地返回到父模板的情况.如果我必须(即我不可能从中创建一个包),我使用在父模板范围内声明为全局的本地minimongo集合.这样,我可以将可重用组件的信息传递给它的父组件.
示例:上传模板.我使用minimongo来存储每个上传文件的名称,大小,类型,状态和URL.minimongo集合在父表单模板和子上传器模板之间共享.
底线:我只使用Session变量来获取基本信息和全局信息.如果我需要全局共享的数据结构太复杂/太大,我依赖于一个集合.
我很想知道我是否做对了,所以这是一个答案,而不是一个测试,看看人们是否同意我的做事方式.欢迎提出所有意见和建议.
会话变量得到了糟糕的说唱.事实是,在你的应用变大之前,它们就可以了.你知道什么时候离开Session vars的时候:
isColumnHidden意味着什么?)或者,会话变量形成自然集群(工具提示3个会话变量,标签5个变量等).那么,你如何解决每个问题?
对于第一个示例,请创建一个包.例如,在我较大的项目之一,我创建一个rightSideMenu和leftSideMenu包.每个都有自己的ReactiveDict,我导出到全局范围(例如rightMenu.RD.get('col1Hidden')).这使方法模块化.我可以完全重写我的菜单代码,但只要我仍然公开ReactiveDict,API保持不变.也就是说,我仍然使用Session var来显示/隐藏左右菜单.为什么?因为Session是菜单的完美用途.我不希望隐藏的菜单通过浏览器会话持续存在(永远关闭你不知道如何重新打开的东西?),但我确实希望它通过路由持续存在.换句话说,我希望它能够持续用于浏览会话.
如果您希望URL保存会话信息,则需要使用params或查询参数.例如,如果您有一个包含100个标记的地图,并且用户希望通过选择特定标记将该页面发送给他的伙伴,那么网址就像是这样的url.com/marker20.但为何停在那里?您还可以包含地图中心的lat和lng : url.com/marker/40.23432/122.2342. 也许那太多了,也许不是.你决定.在您的示例中,这比存储isTag在会话var中更有意义,因为它允许人们将其加入书签,使用后退按钮,共享它,并在不使用鼠标的情况下进行更改(是的,您的用户库与我一样懒) .
关于当前设置的另一个注意事项是,您正在使用标记来处理互斥的内容,从而导致有条件的地狱.如果你有2个不能同时存在的变量,请停止并重新考虑设计.所以,如果我不想使用会话变量,我会做类似的事情:
currentTemplate = Session.get('filter')
{{Template.dynamic template=currentTemplate}}
Run Code Online (Sandbox Code Playgroud)
最后,您需要考虑的不仅仅是ReactiveVariables.依赖关系怎么样?并非每个模块都需要访问每个其他模块的依赖关系.集合,方法甚至CSS也是如此.我说让它有机地生长,当它击中你时"嘿,这是一个组件"然后把它变成一个包,输出一个变量,并保持模块化.在那之前,Session vars很好.