Javascript 如何将自定义方法重新加载到反序列化的FabricJS对象?

Javascript 如何将自定义方法重新加载到反序列化的FabricJS对象?,javascript,fabricjs,Javascript,Fabricjs,我已经在一个项目中熟悉了w/FabricJ 我有一个自定义类,它扩展了fabric.Polyline。这个自定义类有许多自定义方法。我的问题是:当我序列化整个画布并稍后使用loadFromJSON()再次加载它时,自定义方法不再存在… 我注意到序列化之前/之后的对象并不完全相同。事实上,我们可以看到,序列化之后,方法myCustomClassMethod()不再位于对象的\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu中:

我已经在一个项目中熟悉了w/FabricJ

我有一个自定义类,它扩展了
fabric.Polyline
。这个自定义类有许多自定义方法。我的问题是:当我序列化整个画布并稍后使用loadFromJSON()再次加载它时,自定义方法不再存在…

我注意到序列化之前/之后的对象并不完全相同。事实上,我们可以看到,序列化之后,方法
myCustomClassMethod()
不再位于对象的
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
中:

我知道loadFromJSON()有一个用于重新添加事件监听器的
revivier()
方法,但是如何重新添加方法呢?如果说我需要添加一个fromObject()方法来保存/恢复对象,我尝试过使用它,但没有成功

也可能是我的反序列化对象是“常规”对象,而不是fabricjs对象实例。但我还没有看到如何使它再次成为织物对象

我们在下面。正如您所看到的,若在画布重新加载之前调用该方法,则该方法有效,但若在画布重新加载之后调用,则该方法无效

//围绕本机画布元素创建包装器(id=“treeCanvas”)
var canvas=new fabric.canvas('treeCanvas'{
allowTouchScrolling:是的,
});
//取消下面的注释日志以检查对象
canvas.on('mouse:up',函数(e){
如果(例如,目标!=null){
//console.log(如target);
}
});
//我的TreeNode自定义类
var TreeNode=fabric.util.createClass(fabric.Polyline{
初始化:函数(X、Y、armsArray、选项){
选项| |(选项={});
this.callSuper('initialize',options);
这个.X=X;
这个。Y=Y;
this.armsArray=armsArray;
这个.set({宽度:160,高度:50,originX:'center',originY:'center'});
set({left:this.X,top:this.Y,fill:'rgba(255,255,255,0)”,stroke:'black',selective:true});
这是setCoords();
this.set({pathOffset:{x:0,y:25}});
为了(这一点,阿姆萨雷){
this.points.push({x:point[0],y:point[1]});
this.points.push({x:0,y:0});
}
},
_渲染:函数(ctx){
这个.callSuper(“'u render',ctx”);
},
//这是序列化后消失的方法
myCustomClassMethod:函数(){
set({stroke:'green'});
canvas.renderAll();
}
});
//将自定义类的实例添加到画布
var node1=新的树节点(100100,[-8050],[8050],[]);
canvas.add(node1);
canvas.renderAll();
//node1.myCustomClassMethod();//方法在序列化+反序列化之前工作
var stringifiedCanvas=JSON.stringify(canvas);
loadFromJSON(stringifiedCanvas,canvas.renderal.bind(canvas));
node1.myCustomClassMethod();//方法在反序列化后不再工作

我远远不是一名
fabricjs
专家,我做的事情有些不同,但你遗漏了几个重要部分(在下面的代码中用“**更改”标记)

希望这是一些帮助


//围绕本机画布元素创建包装器(id=“treeCanvas”)
var canvas=new fabric.canvas('treeCanvas'{
allowTouchScrolling:是的,
});
//取消下面的注释日志以检查对象
canvas.on('mouse:up',函数(e){
如果(例如,目标!=null){
//console.log(如target);
}
});
//**更改:在结构实例上定义Treenode
fabric.TreeNode=fabric.util.createClass(fabric.Polyline{
//**更改:定义类型
类型:'treeNode',
初始化:函数(X、Y、armsArray、选项){
选项| |(选项={});
this.callSuper('initialize',options);
这个.X=X;
这个。Y=Y;
this.armsArray=armsArray;
这台({
宽度:160,
身高:50,
原文:“中心”,
原创:“中心”
});
这台({
左:这个.X,
托普:这个,
填充:空,
笔画:“黑色”,
可选:真
});
这是setCoords();
这台({
补偿:{
x:0,,
y:25
}
});
为了(这一点,阿姆萨雷){
这个。点。推({
x:点[0],
y:第[1]点
});
这个。点。推({
x:0,,
y:0
});
}
},
_渲染:函数(ctx){
这个.callSuper(“'u render',ctx”);
},
//**更改:序列化时导出自定义方法
toObject:function(){
返回fabric.util.object.extend(this.callSuper('toObject'){
myCustomClassMethod:this.myCustomClassMethod
});
},
myCustomClassMethod:函数(x、y、颜色){
//log(“myCustomClassMethod”)
//console.log(this.myCustomClassMethod)
这台({
左:x,,
上图:y,
笔画:颜色,
冲程宽度:10
});
canvas.renderAll();
}
});
fabric.TreeNode.fromObject=函数(对象,回调){
//console.log(对象)
};
var node1=新结构的树节点(100100[
[-80, 50],
[80, 50]
], []);
canvas.add(node1);
canvas.renderAll();
//反序列化
var stringifiedCanvas=JSON.stringify(canvas);
loadFromJSON(stringifiedCanvas,canvas.renderal.bind(canvas));
//**更改:需要获取对已还原对象的引用
var restored=canvas.getObjects()[0]
///console.log(已还原)
myCustomClassMethod(200,50,“红色”)


只是想一想,您是否考虑过允许反序列化和执行方法的安全风险?(可能注入包含xss攻击的恶意代码)@melchiar-TY以获取评论。我真的不太了解那个TBH。如果我只是序列化/反序列化我自己定义的方法,这还会有风险吗?(我的意思是,我不会反序列化“外部”JSON文件)。当用户能够提交他们的序列化画布时,这只是一个问题,他们可能已经将代码注入了.TYVM for yo