开发者问题收集

尝试从 JSON 加载阶段时出现“未捕获类型错误:无法设置未定义的属性‘容器’”

2020-06-28
1429

每次我尝试执行 Konva.Node.create 时,都会出现错误:“Uncaught TypeError:无法设置未定义的属性‘container’”。据我所知,我使用的数据是正确格式的 JSON,在初始阶段使用 toJSON 后保存到文件中并从文件中检索。我将不胜感激任何帮助解决此问题的方法。我已将数据的控制台日志发布在下面,谢谢!:

{
    "attrs[width]": "754",
    "attrs[height]": "647",
    "className": "Stage",
    "children[0][className]": "Layer",
    "children[0][children][0][attrs][rotateEnabled]": "false",
    "children[0][children][0][attrs][enabledAnchors][]": [
        "top-left",
        "top-right",
        "bottom-left",
        "bottom-right",
    ],
    "children[0][children][0][className]": "Transformer",
    "children[0][children][1][attrs][draggable]": "true",
    "children[0][children][1][attrs][id]": "square1",
    "children[0][children][1][className]": "Group",
    "children[0][children][1][children][0][attrs][x]": "559",
    "children[0][children][1][children][0][attrs][y]": "342.5",
    "children[0][children][1][children][0][attrs][name]": "Square",
    "children[0][children][1][children][0][attrs][width]": "100",
    "children[0][children][1][children][0][attrs][height]": "100",
    "children[0][children][1][children][0][attrs][fill]": "white",
    "children[0][children][1][children][0][attrs][stroke]": "black",
    "children[0][children][1][children][0][className]": "Rect",
    "children[0][children][1][children][1][attrs][name]": "text",
    "children[0][children][1][children][1][attrs][text]": "Storage",
    "children[0][children][1][children][1][attrs][align]": "center",
    "children[0][children][1][children][1][attrs][verticalAlign]": "middle",
    "children[0][children][1][children][1][attrs][x]": "559",
    "children[0][children][1][children][1][attrs][y]": "382.5",
    "children[0][children][1][children][1][attrs][fontSize]": "15",
    "children[0][children][1][children][1][attrs][width]": "100",
    "children[0][children][1][children][1][attrs][fill]": "black",
    "children[0][children][1][children][1][className]": "Text",
}

这是引发错误的方法 loadStage。我将代码保存到 JSON 文件,并使用节点检索它。然后将其传递给此处的函数:

function loadStage(stage) {
    $.ajax({
        type: 'GET',
        //contentType: 'application/json',
        url: '/getstage',
        success: function (data) {
            console.log("'"+data+"'");
            if(data !== "")
            {
                stage = Konva.Node.create(data, 'canvas');
            }
        }
    });
}

这是在更新时保存代码的方法(当我添加新形状时):

function saveStage() {
    var json = stage.toJSON();
    $.ajax({
        type: 'POST',
        //contentType: 'application/json',
        data: JSON.parse(json),
        url: '/savestage',
        success: function (data) {
            
        }
    });
}

以及错误消息:

Uncaught TypeError: Cannot set property 'container' of undefined
    at Function.ct._createNode (konva.min.js:12)
    at Function.ct.create (konva.min.js:12)
    at Object.success (facilitytracker.js:46)
    at c (jquery.min.js:2)
    at Object.fireWith [as resolveWith] (jquery.min.js:2)
    at l (jquery.min.js:2)
    at XMLHttpRequest.<anonymous> (jquery.min.js:2)
ct._createNode @ konva.min.js:12
ct.create @ konva.min.js:12
success @ facilitytracker.js:46
c @ jquery.min.js:2
fireWith @ jquery.min.js:2
l @ jquery.min.js:2
(anonymous) @ jquery.min.js:2
load (async)
send @ jquery.min.js:2
ajax @ jquery.min.js:2
loadStage @ facilitytracker.js:38
(anonymous) @ facilitytracker.js:9
e @ jquery.min.js:2
t @ jquery.min.js:2
setTimeout (async)
(anonymous) @ jquery.min.js:2
c @ jquery.min.js:2
fireWith @ jquery.min.js:2
fire @ jquery.min.js:2
c @ jquery.min.js:2
fireWith @ jquery.min.js:2
ready @ jquery.min.js:2
B @ jquery.min.js:2
2个回答

以下是从一个阶段到另一个阶段的保存和恢复的简化示例。这是我能想到的最简单的保存和恢复步骤。我建议您浏览一下您的代码,确认阶段变量已定义,并且“容器”元素存在。您可能会发现一个简单的错误。

// Set up the canvas and shapes
var s1 = new Konva.Stage({container: 'container1', width: 300, height: 200});
var layer1 = new Konva.Layer({draggable: false});
s1.add(layer1);

// draw a rect so we have something to save and load.
var r1 = new Konva.Rect({x: 30, y: 20, width: 200, height: 100, fill: 'cyan' })    
layer1.add(r1);

 var oval = new Konva.Ellipse({
    x: s1.width() / 2,
    y: s1.height() / 2,
    radiusX: 100,
    radiusY: 50,
    fill: 'yellow',
    stroke: 'black',
    strokeWidth: 4,
  });
  
layer1.add(oval);
      
s1.draw() // First draw of canvas.

// List for the go button to be clicked, then save the stage and load it into container 2.
$('#go').on('click', function(){
  
  $('#container2').css('visibility', 'visible');

  // save stage as a json string
  var json = s1.toJSON();


  var s2 = Konva.Node.create(json, 'container2');
  s2.draw();
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://cdn.rawgit.com/konvajs/konva/1.6.5/konva.min.js"></script>
<p>Click the Save & Load button to save the left hand stage to a serialized string and have that string laoded into a new stage on the right.

</p>

<p>
<button id='go'>Save & load</button>
</p>
<div id='container1' style="display: inline-block; width: 300px, height: 200px; background-color: silver; overflow: hidden; border: 4px solid cyan;"></div>
<div id='container2' style="display: inline-block; width: 300px, height: 200px; background-color: silver; overflow: hidden; border: 4px solid magenta; visibility: hidden;"></div>
Vanquished Wombat
2020-06-28

结果发现这是 fs.readfile 和 fs.writefile 格式化 JSON 的方式的问题。我最终找到了一种解决方法,尽管我并不完全满意。我将 JSON 转换为字符串,并使用 substring 和 split 方法删除多余的字符。这很烦人,因为它是有效的 JSON,但不是 Konva 可以接受的格式。

Sam Mortinger
2020-06-29