使用 Knockout.JS 通过 JSON 将 HTML 复选标记传递到表中

Posted

技术标签:

【中文标题】使用 Knockout.JS 通过 JSON 将 HTML 复选标记传递到表中【英文标题】:Passing HTML checkmark through JSON into a table with Knockout.JS 【发布时间】:2015-01-24 09:02:59 【问题描述】:

我有一个使用 knockout.JS 填充了一堆数据的大表。其中一些数据需要替换为 html 复选框和选择,但它不是一致的。我有一个包含我所有数据的对象数组。为简化起见,每个对象都有 3 个属性。标题、值和格式。我试图只更改格式为复选框或选择的表格的值单元格。

例如,原来的表格是这样的:

标题 |价值 |格式 --------+-------+-------- 身高 | 5 |整数 长度 | 7 |整数 真实 | 1 |复选框 要求 | 0 |复选框

但我想要这样:

标题 |价值 |格式 --------+-------+-------- 身高 | 5 |整数 长度 | 7 |整数 真实 | ☑ |复选框 要求 | ☐ |复选框

示例代码(php):

首先我遍历对象数组,如果格式属性是“复选框”,则插入 HTML 复选框而不是值。

        .....loop....

        if($format == "Checkbox")
            $value = '<input type="checkbox"></input>';
        

然后我使用json_encode(array);

(JS) 这里是ajax成功

success: function(data)
    var valve = JSON.parse(data);
;

然后我循环遍历阀门数组中的每个对象并提取所需的属性:

for(var i=0, l=valve.length; i<l; i++)         
    if(valve[i]['formatfor(var i=0, l=valve.length; i<l; i++)          
        if(valve[i]['format']=="checkbox")
            var formatHTML = '<input type="checkbox"></input>';
        ;

        var dataRow =
            title: valve[i]['title'],
            value: valve[i]['value'],
            format: formatHTML
        ;

        //push each row to valveData which is a ko.observableArray()    
        self.valveData.push(dataRow);

;          

我的表格填充得很好,但我最终得到的是原始 HTML:&lt;input type="checkbox"&gt;&lt;/input&gt; 而不是实际元素。这是淘汰赛的问题还是我的 JSON 的问题? MY JSON 在引号中返回 HTML,因为它存储为字符串,有没有办法删除它们或其他什么?

更高级别的问题,我应该这样做吗?或者我应该在我的数据模型中处理格式类型。

【问题讨论】:

【参考方案1】:

问题是您根本没有使用 Knockout。

对于使用 Knockout:

返回一个带有属性的纯 JSON 对象(¡¡不是生成 HTML !!) 可选:理想情况下,使用 ajax 获取 JSON,而不是直接在页面正文中编写对象定义。即,您的 php 代码应该返回一个 JSON 对象,并且您应该使用类似 jQuery.getJSON 的东西直接从 PHP 服务器获取该数据 将您的 JSON 对象插入到敲除 viewModel,即映射 JSON 中的属性。您可以使用 ko.mapping 插件自动执行此操作。这会将您的 JSOn 对象数组转换为 observableArray,并将您的 JSON 对象属性转换为 observable 创建模板以呈现对象 将对象绑定到模板

至于显示一个复选框或者只是文本你可以使用敲除if绑定。

您的模板应该看起来像这样:

<table>
   <tbody data-bind='foreach: row'>
      <tr>
         <td data-bind='text: title'>
         </td>
         <td>
            <!-- ko if: format=='Checkbox' -->
               <input type='check' data-bind='checked: value`/>
            <!-- /ko -->
            <!-- ko if: format!='Checkbox' -->
               <!-- ko text: value --><!-- /ko -->
            <!-- /ko -->
         </td>
         <td data-bind='text: format'>
         </td>
      </tr>
   </tbody>
</table>

您的 JSON 对象应该是这样的:

[
    "title": "height", "value": "5", "format": "int",
    "title": "length", "value": "7", "format": "int",
    "title": "true", "value": "1", "format": "checkbox",
    "title": "required", "value": "0", "format": "checkbox",
]

你的 javascript 应该是这样的:

$.getJSON('... your PHP url ...').done(function(data) 
    var viewModel = // construct from data, by hand, or with ko.mapping
    ko.applyBindings(viewModel);
);

注意:如果你不使用AJAX,你可以直接在页面内容上定义var或者model,并且只调用applyBindings注意:我不是 PHP 专家,但我知道有一种方法可以将 PHP 对象直接序列化为 JSON,因此制作 AJAX 部分非常容易。 Please, see this.

【讨论】:

我一定没有明确表示我删除了大部分代码以节省空间。我正在执行您的所有建议(JSON、AJAX、Viewmodel、绑定到可观察数组等)。您对无容器控件语法的建议正是我所需要的,因此感谢您。我编辑了您的代码,因为您弄乱了导致整个事情中断的结束注释标签。 ( > 而不是 -->) 抱歉,我试图编辑您的帖子以纠正您的错误,但我想这不是正确的做事方式,因此被拒绝了。我用正确的代码添加了我自己的答案。【参考方案2】:

上面的一些无容器控件是不正确的,但这个想法很好。这是固定代码

<table>
   <tbody data-bind='foreach: row'>
      <tr>
         <td data-bind='text: title'>
         </td>
         <td>
            <!-- ko if: format=='Checkbox' -->
               <input type='checkbox' data-bind='checked: value`/>
            <!-- /ko -->
            <!-- ko if: format!='Checkbox' -->
               <!-- ko text: value --><!-- /ko -->
            <!-- /ko -->
         </td>
         <td data-bind='text: format'>
         </td>
      </tr>
   </tbody>
</table>

【讨论】:

以上是关于使用 Knockout.JS 通过 JSON 将 HTML 复选标记传递到表中的主要内容,如果未能解决你的问题,请参考以下文章

Knockout JS 中的模型

Knockout.js 和 Jquery Mobile

Knockout JS 使用 JSON 迭代一个对象数组

通过 knockout.js 将选中的复选框值传递给 javascript

Knockout JS 将元素的属性绑定到另一个元素

Knockout JS绑定元素的属性为另一个元素