我有一个任意的(E)JSON,可以在我的Meteor应用程序中通过客户端将其创建并通过电线发送到服务器。它使用RegExp对象将结果归零:
RegExp
# on the client selector = "roles.user": { "$ne": null } "profile.email": /^admin@/gi
在客户端,一切都很好,但是如果我通过Meteor.call或将其传递给服务器Meteor.subscribe,则生成的(E)JSON采用以下形式:
Meteor.call
Meteor.subscribe
# on the server selector = "roles.user": { "$ne": null } "profile.email": {}
…某处工程师在内部死亡。
Web上有大量资源说明为什么RegEx无法通过JSON.stringify/ JSON.parse或等效EJSON方法进行序列化。
JSON.stringify
JSON.parse
EJSON
我不认为RegEx序列化是不可能的。那怎么办呢?
在查看了HowTo和Meteor EJSON文档之后,我们可以使用EJSON.addType方法序列化RegEx 。
EJSON.addType
扩展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上面定义的对象。
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));