我觉得这很容易但是,是的......事实并非如此。我已经发布了一个朝着同一方向发出的问题,但提出了另一个问题。
我有歌曲的集合,它具有时间属性(歌曲的播放时间)。在表单验证和后端验证中,此属性应处理不同!
/^\d{1,2}:?[0-5][0-9]$/
的字符串(因此格式“mm:ss “或 mmss )。这是我的javascript
// schema for collection
var schema = {
time: {
label: "Time (MM:SS)",
type: Number // !!!
},
// ...
};
SongsSchema = new SimpleSchema(schema);
Songs.attachSchema(SongsSchema);
// schema for form validation
schema.time.type = String // changing from Number to String!
schema.time.regEx = /^\d{1,2}:?[0-5][0-9]$/;
SongsSchemaForm = new SimpleSchema(schema);
这是我的模板:
{{>quickForm
id="..."
type="insert"
collection="Songs"
schema="SongsSchemaForm"
}}
我想要的工作流程是:
回来的路。
我首先尝试使用钩子formToDoc
并将字符串转换为秒(数字)。
我发现,通过给定架构(对于表单)的表单验证发生在转换为`formToDoc之后,因此它已经是一个数字验证为字符串失败。
这就是为什么我寻找另一个在验证表单后触发的钩子。这就是我尝试的原因......
我使用了钩子before.insert
和数据库的工作方式!
AutoForm.hooks({
formCreateSong: {
before: {
insert: function (doc) {
// converting the doc.time to Number (seconds)
// ...
return doc;
}
},
docToForm: function (doc) {
// convert the doc.time (Number) back to a string (MM:SS)
// ...
return doc;
}
}
});
当我实施update
- 表单时,docToForm
未被调用,因此更新形式中的数值是(以秒为单位)。
我正在寻找一种解决这个问题的“流星自动”方法。
非常感谢你阅读并希望得到一个好的答案; - )
答案 0 :(得分:0)
我觉得time
应该在视图内部而不是在模型内部格式化。所以这里是time
我使用的模式:
...
function convertTimeToSeconds (timeString) {
var timeSplit = timeString.split(':')
return (parseInt(timeSplit[0]) * 60 + parseInt(timeSplit[1]))
}
time: {
type: Number,
autoValue: function () {
if(!/^\d{1,2}:?[0-5][0-9]$/.test(this.value)) return false
return convertTimeToSeconds(this.value)
}
}
...
这当然有一个小缺点。您不能再使用quickForm
- 帮助程序,但必须使用autoForm
。
然后显示值{我只需find
songs
,然后写一个帮手:
Template.registerHelper('formateTime', function (seconds) {
var secondsMod = seconds % 60
return [(seconds - secondsMod) / 60, secondsMod].join(':')
})
在你的模板中:
{{ formatTime time }}
答案 1 :(得分:0)
简单的答案是不验证字符串,验证字符串转换成的数字。
使用simpleschema,您所要做的就是创建自定义验证。该自定义验证将获取字符串,将其转换为数字,然后验证该数字。
然后,当你从数据库中取出它时,你必须拿下那个数字&将其转换为字符串。现在,simpleschema本身并没有做到这一点,但在你的表单中做起来很容易。
现在,如果你想获得幻想,请按照我的建议:
添加新架构字段:
SimpleSchema.extendOptions({
userValue: Match.Optional(Function),
dbValue: Match.Optional(Function),
});
然后,在time
字段中添加一个函数(存储为日期字段):
userValue: function () {
return moment(this.value).format('mm:ss');
},
dbValue: function () {
return timeToNumber(this.value);
}
然后,创建一个将timeString转换为数字的函数(快速而肮脏的示例,您必须添加错误检查):
function timeToNumber(str) {
str.replace(':',''); //remove colon
var mins = +str.substr(0,2);
var secs = +str.substr(2,2);
return mins * 60 + secs;
}
然后,对于实时验证,您可以使用schema.namedContext().validateOne
。要更新数据库,只需发送timeToNumber(input.value)
即可。