使用递归模型时如何使用挖空的样式绑定



我正在使用Knockout 3.0.0,并且正在使用嵌套模型:一个形状可以包含任意数量的其他形状。

这是示例数据:

var process =
{
"type": "process",
"id": "singletask",
"name": "Default Process",
"children": [
    {"type": "task",
     "id": "Task_1",
     "name": "Task 1",
     "bounds": {
        "x": "435.0",
        "y": "175.0",
        "height": "50.0",
        "width": "110.0"
      },
      "children": []
    }
    ]
};

我按如下方式构建视图模型:

function getBounds(bounds) {
    var res = {
                  "x": ko.observable(bounds.x),
                  "y": ko.observable(bounds.y),
                  "height": ko.observable(bounds.height),
                  "width": ko.observable(bounds.width)
             }
    return res;
}
/* recursively construct view model out of JSON data */
function getPartOfViewModel(data) {
    var children= [];
    $.each(data.children, function(i, e) {
        var res = getPartOfViewModel(e);
        children.push(res);
    });
    var res = {
        "type": ko.observable(data.type),
        "template": data.type + "-template",
        "id": ko.observable(data.type),
        "name": ko.observable(data.type),
        "children": children
    }
    // not all elements have bounds
    if (data.bounds) {
        $.extend(res, {"bounds":getBounds(data.bounds)});
    }
    return res;
}
var viewModel = getPartOfViewModel(process);

我认为有问题,因为在尝试创建计算条目时我无法使用"this"。(这似乎是一个单独的问题)

HTML非常简单

<div data-bind="foreach: $data.children" class="drawingarea">
    <div data-bind="template: { name: $data.template, data: $data }"></div>
</div>
<script type="text/html" id="task-template">
    <div data-bind="css: type, style: {left: $data.bounds.x + 'px', top: bounds.top + 'px', height: $data.bounds.height + 'px', width: $data.bounds.width + 'px'}">
        <span data-bind="text: $data.bounds.x"></span>/<span data-bind="text: $data.bounds.y"></span>
        <span data-bind="text: $data.bounds.height"></span>/<span data-bind="text: $data.bounds.width"></span>
    </div>
</script>

问题是呈现的形状包含文本435.0/175.0 50.0/110.0但没有正确的位置。我做错了什么?

完整示例:http://jsbin.com/robukuvu/1

工作演示

您的代码很好,您只需要进行两项更改:

  1. 首先, 对于 css 属性top,您需要添加$data并将top替换为 y 。 所以它应该是顶部:$data.bounds.y() + 'px'
  2. 其次, 你的对象xyheightwidth它们都是可观察对象,那么在你的绑定中不需要使用(),也不需要+ 'px'

所以最终正确的HTML代码:

<div data-bind="css: type, style: {left: $data.bounds.x, top: $data.bounds.y, height: $data.bounds.height, width: $data.bounds.width}">

试试这个:

data-bind="style: {left: $data.bounds.x() + 'px', top: $data.bounds.y() + 'px', height: $data.bounds.height() + 'px', width: $data.bounds.width() + 'px'}"

1.在第top部分中,您错过了$data前缀。

阿拉伯数字。您的bounds结构中没有top字段,您实际上在getBounds()函数中将其命名为y

3.由于您使用的是可观察量,因此 Knockout 能够处理$data.bounds.x(例如),而无需调用可观察量,但由于您将"px"连接到它,它会尝试将表达式作为一个整体进行评估,结果实际上是附加到可观察函数的"px"。

这就是为什么你需要$data.bounds.x() + 'px'而不是$data.bounds.x + 'px'.

最新更新