【问题标题】:Knockout.js Pre-seed ObservableArrayKnockout.js 预种子 ObservableArray
【发布时间】:2013-01-12 02:29:51
【问题描述】:

我不确定我是否在这里尝试做太多事情,但这是场景。我有一个 asp.net mvc 页面,在第一次加载时,它使用 mvc 框架中的标准 foreach 机制在视图中返回一个数据表。如果用户启用了 javascript,我想使用敲除来更新表格。有没有办法让淘汰赛从 dom 表中读取数据并将该数据用作初始可观察集合。从那以后,我会使用 knockout 和 ajax 来添加、编辑或删除数据。

简而言之,我需要将一个 html 表解析为一个可淘汰的可观察集合。

【问题讨论】:

  • 你可以在一个javascript变量中设置初始数据,然后添加到observable而不是在服务器中使用foreach。
  • 您在执行此操作时遇到了什么问题?完全有可能,
  • @MuriloKunze:他说 JavaScript 可以被禁用。如果 JavaScript 被禁用,他就不能使用 JavaScript 变量。
  • 我正在尝试同时支持 JavaScript 和非 JavaScript 场景。在这两种情况下,我最初都是从服务器加载页面。但是,如果他们确实启用了 JavaScript,我想使用 JavaScript 来“逐步增强”页面。
  • 有什么问题吗?这是完全可能的。

标签: javascript asp.net-mvc knockout.js


【解决方案1】:

我已经开始编写代码了:

这是基本标记:

<table id="table" data-bind="template: { name: 'table-template' }">
  <thead>
    <tr>
      <th>Name</th>
      <th>Surname</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Richard</td>
      <td>Willis</td>
    </tr>
    <tr>
      <td>John</td>
      <td>Smith</td>
    </tr>
  </tbody>
</table>

<!-- Here is the template we'll use for re-building the table -->

<script type="text/html" id="table-template">
  <thead>
    <tr>
      <th>Name</th>
      <th>Surname</th>
    </tr>
  </thead>
  <tbody data-bind="foreach: data">
    <tr>
      <td data-bind="text: name"></td>
      <td data-bind="text: surname"></td>
    </tr>
  </tbody>
</script>

Javascript:

(function() {

  function getTableData() {
    // http://johndyer.name/html-table-to-json/

    var table = document.getElementById('table');
    var data = [];
    var headers = [];

    for (var i = 0; i < table.rows[0].cells.length; i++) { 
      headers[i] = table.rows[0].cells[i].innerHTML.toLowerCase().replace(/ /gi, '');
    }
    // go through cells 
    for (var i = 1; i < table.rows.length; i++) {
      var tableRow = table.rows[i];
      var rowData = {};
      for (var j = 0; j < tableRow.cells.length; j++) {
        rowData[headers[j]] = tableRow.cells[j].innerHTML;
      }
      data.push(rowData);
    }

    return data;     
  }

  var Vm = function () {  
    this.data = ko.observableArray(getTableData());     
  };

  ko.applyBindings(new Vm(), document.getElementById('table'));
})();

您可以使用映射插件扩展此概念,为每一行创建可观察对象:http://knockoutjs.com/documentation/plugins-mapping.html

在此处查看演示:http://jsfiddle.net/CShqK/1/

编辑:我并不是说这是最好的方法,因为遍历一个大表来获取数据可能会很昂贵。我可能会按照此线程中其他人的建议在页面中输出 JSON。

【讨论】:

  • 花了几天的时间来处理这些东西,我开始认为在同一个视图中混合对 javascript 和非 javascript 浏览器的支持只是一个坏主意。我还没有在网上看到一个干净地完成的例子。话虽如此,您的解决方案有效并解决了我对两次下载相同数据的担忧。我最终使用了 Chris Fletcher 的脚本,它基本上做了同样的事情:fletchzone.com/post/jQuery-HTML-Table-to-JSON-Version-20!.aspx
【解决方案2】:

用数据而不是解析 html 表来提供你的 observable 数组怎么样

myArray: ko.observableArray(@Html.Raw(Json.Encode(Model.myTableData)))

如果真的需要去解析html的方式,可以使用下面的代码

var tableData = $('#myTable tr').map(function(){
return [
    $('td,th',this).map(function(){
        return $(this).text();
    }).get()
];
}).get();
$(document).ready(function() {
    var myData = JSON.stringify(tableData);
    alert(myData)
});

这是一个显示实际代码的小提琴: http://jsfiddle.net/FWCXH/

【讨论】:

  • 这确实有效;但是,它现在返回数据 2 次。一次是html,一次是json。有谁知道如何将html解析成json?
  • 我在答案中添加了一个将 html 表转换为 json 的 javascript 函数
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-06
  • 1970-01-01
  • 1970-01-01
  • 2013-11-23
  • 1970-01-01
  • 1970-01-01
  • 2012-04-01
相关资源
最近更新 更多