Importing/Exporting 具有 devs.Model 个元素的 JointJS 图

Importing/Exporting JointJS Graphs with devs.Model Elements

所以我正在尝试为我的 JointJS 应用程序实现一个 "Import Graph" 功能。我正在使用的所有元素都继承自 devs.Model 这样,

var myCustomShape = new joint.shapes.devs.Model();

这些形状包括 devs.Model 之上的自定义属性,其中包括子对象和功能属性。

使用 JSON.parse 导入我的图表导致错误:

joint.js:13580 Uncaught Error: dia.ElementView: markup required
    at child.renderMarkup (joint.js:13580)
    at child.render (joint.js:13616)
    at child.protoProps.render (joint.js:9692)
    at child.renderView (joint.js:17645)
    at child.resetViews (joint.js:17691)
    at triggerEvents (backbone.js:370)
    at triggerApi (backbone.js:356)
    at eventsApi (backbone.js:155)
    at child.Events.trigger (backbone.js:346)
    at triggerEvents (backbone.js:371)

我阅读了 JointJS 文档:

Keep in mind the general limitations of the JSON format. Some commonly used >native JavaScript data types (including Function, Date, and undefined) are >not supported. The variables that have values of these types will not be >persisted. Among other things, this means that if persistence is important in >your application, you should choose to define custom element/link subtypes >instead of embedding custom functions into default joint.dia.Element and >joint.dia.Link types.

Additionally, if you want to make use of the JSON objects and directly store >them into MongoDB, you should remember its additional restriction on object >keys starting with the . (dot) or $ (dollar sign) symbols. Those are reserved >for internal use of the MongoDB system. This is significant in the context of >JointJS because it precludes the use of CSS-style selectors in the attrs >arrays of your Elements and Links. Therefore, if persistence is important to >you and you want to save data directly to MongoDB, you should always define >custom subelement selectors in the markup of your custom elements instead of >relying on CSS-style selectors.

我想知道这里是否有任何已知的解决方法可以用来保存我的图形以及所有自定义元素。请温柔点,这是我的第一个 javascript 应用程序,第一次使用 JSON 和第一次使用 JointJS。

我已经回答了我自己的问题。 如果您从一个形状继承而不扩展它,则在您的新形状声明中不需要任何标记。这是我使用的声明形状的旧方法:


OLD CODE DON'T USE THIS

var myCustomShape = new joint.shapes.devs.Model({
    position: { x:50, y:50 },
    size: { width: 75, height: 75 },
    inPorts: ['Input'],
    outPorts: ['Output'],
    attrs: {
        '.label': {
             text: 'Source',
             fill: 'black'
         },
         rect: {
             fill: 'springgreen'
         }
    },
    type: 'custom.myCustomShape'
});

所以我转而扩展 devs.Model 形状,然后像这样制作一个新的类型:


NEW WORKING CODE :)

joint.shapes.custom.myCustomShape = joint.shapes.devs.Model.extend({
            markup: '<g class="rotatable"><g class="scalable"><rect class="body"/></g><image/><text class="label"/><g class="inPorts"/><g class="outPorts"/></g>',
            defaults: joint.util.deepSupplement({
                type: 'custom.myCustomShape',
                size: { width: 75, height: 75 },
                rect: {
                    stroke: '#d1d1d1',
                    fill: 'white'
                },
                circle: {
                    stroke: 'gray'
                },
                '.label': {
                    text: 'Base',
                    'ref-y': -20
                },
                '.inPorts circle': {
                    fill: '#c8c8c8'
                },
                '.outPorts circle': {
                    fill: '#262626'
                },
            }, joint.shapes.devs.Model.prototype.defaults)
        });

并被以下用户使用:

var customShape= new joint.shapes.custom.myCustomShape({
            attrs: {
                '.label': {
                    text: 'My Shape',
                    fill: 'black'
                },
                rect: {
                    fill: 'springgreen'
                }
            },
            position: { x: 50, y: 50 },
            size: { width: 75, height: 75 }
        });
graph.addCell(customShape);

当导出和导入具有这样声明的形状的图形时,一切正常。