我有一个任意的(E)JSON,可以在我的Meteor应用程序中通过客户端将其创建并通过电线发送到服务器。它使用RegExp
对象将结果归零:
# on the client
selector =
"roles.user": { "$ne": null }
"profile.email": /^admin@/gi
在客户端,一切都很好,但是如果我通过
Meteor.call
或Meteor.subscribe
将其传递给服务器,则生成的(E)JSON采用以下形式:# on the server
selector =
"roles.user": { "$ne": null }
"profile.email": {}
...某处工程师在内部死亡。
Web上有大量资源,解释了为什么Regoji无法通过
JSON.stringify
/ JSON.parse
或等效的EJSON
方法进行序列化。我不认为RegEx序列化是不可能的。那怎么办呢?
最佳答案
查看this HowTo和the Meteor EJSON Docs之后,我们可以使用EJSON.addType
方法序列化RegEx。
扩展RegExp -为RegExp提供EJSON.addType
实现所需的方法。
RegExp::options = ->
opts = []
opts.push 'g' if @global
opts.push 'i' if @ignoreCase
opts.push 'm' if @multiline
return opts.join('')
RegExp::clone = ->
self = @
return new RegExp(self.source, self.options())
RegExp::equals = (other) ->
self = @
if other isnt instanceOf RegExp
return false
return EJSON.stringify(self) is EJSON.stringify(other)
RegExp::typeName = ->
return "RegExp"
RegExp::toJSONValue = ->
self = @
return {
'regex': self.source
'options': self.options()
}
调用EJSON.addType -在任何地方执行此操作。最好使它可用于客户端和服务器。这将反序列化上面
toJSONValue
中定义的对象。EJSON.addType "RegExp", (value) ->
return new RegExp(value['regex'], value['options'])
在控制台中测试-不要相信我。你自己看。
> o = EJSON.stringify(/^Mooo/ig)
"{"$type":"RegExp","$value":{"regex":"^Mooo","options":"ig"}}"
> EJSON.parse(o)
/^Mooo/gi
这样一来,您就可以在客户端和服务器上对RegExp进行序列化和解析,可以通过有线方式传递它们,将其保存在Session中,甚至可以存储在查询集合中!
编辑以添加IE10 +错误:错误:在严格模式下不允许分配只读属性由@Tim Fletcher提供
import { EJSON } from 'meteor/ejson';
function getOptions(self) {
const opts = [];
if (self.global) opts.push('g');
if (self.ignoreCase) opts.push('i');
if (self.multiline) opts.push('m');
return opts.join('');
}
RegExp.prototype.clone = function clone() {
return new RegExp(this.source, getOptions(this));
};
RegExp.prototype.equals = function equals(other) {
if (!(other instanceof RegExp)) return false;
return EJSON.stringify(this) === EJSON.stringify(other);
};
RegExp.prototype.typeName = function typeName() {
return 'RegExp';
};
RegExp.prototype.toJSONValue = function toJSONValue() {
return { regex: this.source, options: getOptions(this) };
};
EJSON.addType('RegExp', value => new RegExp(value.regex, value.options));