如何使用knockout.js实现通用CRUD网格?

时间:2012-10-09 09:06:32

标签: model-view-controller knockout.js asp.net-web-api

我有一个非常漂亮的网格,包含创建,检索,编辑和删除功能。我在客户端使用knockout.js,在后端使用WebAPI。

我想将其扩展到许多不同的对象。基本上我有一个List< T>其中T是一个MVC视图模型,淘汰视图和视图模型应该能够根据T计算它们应该是什么样子。

有没有人知道一种简单的方法来显示任何视图模型(具有基于视图模型本身的特定控件进行编辑 - 例如日期的datepicker,字符串的输入,下拉等),并且具有通用的CRUD函数。 / p>

以下是我正在使用的退出HTML的示例(针对特定对象):

<table class="table table-striped table-bordered">
    <thead>
        <tr>
        <th>Value Date</th>
        <th>Position Date</th>
        <th>Book</th>
        <th>Currency</th>
        <th>Currency Base</th>
        <th>Amount1</th>
        <th>Amount2</th>
        <th>Position Type</th>
        <th style="width: 100px; text-align:right;" />
        </tr>
    </thead>
   <tbody data-bind=" template:{name:templateToUse, foreach: pagedList }"></tbody>
</table>

,模板看起来像这样:

<script id="itemsTmpl" type="text/html">
<tr>
    <td data-bind="text: valueDate.formattedDate"></td>
    <td data-bind="text: positionDate.formattedDate"></td>
    <td data-bind="text: book"></td>
    <td data-bind="text: currency"></td>
    <td data-bind="text: currencyBase"></td>
    <td data-bind="text: amount1"></td>
    <td data-bind="text: amount2"></td>
    <td data-bind="text: positionType"></td>
    <td class="buttons">
        <a class="btn" data-bind="click: $root.edit" href="#" title="edit"><i class="icon-pencil"></i></a>
        <a class="btn" data-bind="click: $root.remove" href="#" title="remove"><i class="icon-trash"></i></a>
    </td>
</tr>
</script>

<script id="editTmpl" type="text/html">
<tr>
    <td><input data-bind="datepicker: valueDate.formattedDate, datepickerOptions: { dateFormat: 'yy/mm/dd' }"/></td>
    <td><input data-bind="datepicker: positionDate.formattedDate, datepickerOptions: { dateFormat: 'yy/mm/dd' }"/></td>
    <td><input data-bind="value: book"/></td>
    <td><input data-bind="value: currency"/></td>
    <td><input data-bind="value: currencyBase"/></td>
    <td><input data-bind="value: amount1"/></td>
    <td><input data-bind="value: amount2"/></td>
    <td><input data-bind="value: positionType"/></td>
    <td class="buttons">
        <a class="btn btn-success" data-bind="click: $root.save" href="#" title="save"><i class="icon-ok"></i></a>
        <a class="btn" data-bind="click: $root.cancel" href="#" title="cancel"><i class="icon-remove"></i></a>
    </td>
</tr>
</script>

我希望View和View Model是通用的,而不是如上所述的“硬编码”。我相信别人一定做过这样的事情。

1 个答案:

答案 0 :(得分:2)

一种解决方案是:

  1. AJAX调用获取JSON视图模型列表
  2. 如果列表为空,则不显示任何内容
  3. 如果列表包含项目,请选择第一项并通过属性
  4. 通过循环使用proprties
  5. 开始在客户端上构建视图
  6. 将字符串作为DOM元素附加到主DIV
  7. Wireup淘汰赛
  8. 这种方法存在问题。如果第一个对象的属性为null但在另一个对象中存在,该怎么办?如果是这样,我们就不为它设置元素。

    更好的选择是使用内容协商来获取专用模板:

    因此GET / api / customers将返回客户,但如果您请求text / knockout-template + html,那么您将获得一个淘汰模板作为字符串,然后您附加到DIV和连线淘汰赛。 因此服务器可以使用反射生成模板或为某些模型自定义。