我一直在研究Meteor中的一个小应用程序。我注意到一种代码模式开始让我感到烦恼。
Template.userForm.helpers({
name: function(){
user = Meteor.users.findOne(Session.get('edit-user'));
return user && user.profile.name;
},
_user_id: function(){
user = Meteor.users.findOne(Session.get('edit-user'));
return user && user._id;
},
email: function(){
user = Meteor.users.findOne(Session.get('edit-user'));
return user && user.emails && user.emails[0].address;
},
});
问题在于重复variable && variable.attribute
代码。如果我不编写代码,那么我会得到有关未定义变量的错误。
有更好的方法吗?我错过了什么?
答案 0 :(得分:6)
return variable && variable.attribute
等同于更精细的
if(variable) return variable.attrubite;
return false;
这是必要的,因为如果variable
是null
- 这在页面加载和收集通胀之间一直发生 - 调用variable.attribute
会引发异常:null
不会有属性。
所以不,那张支票没有逃脱。如果这个困扰你,你可以选择另一种味道 - 就我个人而言,我将离开最后一行的实际回报并提前检查正确性:
if(! variable) return null;
return variable.attribute;
可以避免的是这一行 - 所有助手也会重复这一行:
user = Meteor.users.findOne(Session.get('edit-user'));
但是,在上述情况下,所有属性都属于单个对象。那么为什么不通过这个单一对象?
userForm.js:
Template.userForm.user = function() {
return Meteor.users.findOne(Session.get('edit-user'));
}
userForm.html:
<template name="userForm">
<span data-id="{{user._id}}">
Name: {{user.name}}, email: {{user.email}}
</span>
</template>
甚至:
<template name="userForm">
{{#with user}}
<span data-id="{{_id}}">
Name: {{name}}, email: {{email}}
</span>
{{/with}}
</template>
答案 1 :(得分:3)
您可能希望定义一个全局帮助程序,尤其是在使用Session
变量时,这些变量将更加灵活并允许跨多个模板使用:
Handlebars.registerHelper("getUserProperty", function(field) {
var user = Meteor.users.findOne(Session.get('edit-user'));
return user && user[field];
});
然后,你可以将它与{{getUserProperty "username"}}
或类似的东西一起使用。您还可以允许field
参数更加花哨,以便您可以使用"profile.name"
之类的内容并重复索引到对象中。类似下面的内容,虽然你绝对可以支持更多的解析逻辑:
Handlebars.registerHelper("getUserProperty", function(field) {
var item = Meteor.users.findOne(Session.get('edit-user'));
var keys = field.split(".");
$(keys).each( function(idx, value) {
item = item && item[value];
});
return item;
});
有一点需要注意:在声明局部变量时,您应该更多地使用var
。你不必在Coffeescript中这样做,但它在Javascript中非常重要。