【发布时间】:2012-04-03 22:12:58
【问题描述】:
我遇到了 Knockout 中 ViewModel 结构的问题。
更新
结束更新
概述
- 我想从 MVC 操作返回一个模型并使用映射 淘汰赛扩展以创建从 JSON 到 ViewModel 的 observable。
- 表中的显示项目只有一个字段是可编辑的,而这 字段是下拉列表,但它导致项目的所有属性都更新 价值观。
- 将模型发布回 MVC 操作。
说明
我正在使用映射扩展将从 MVC 操作返回的 JSON 模型映射到淘汰模型,我的模型如下所示:
public class SomeClassInput
{
public string Help { get; set; }
public IEnumerable<SomeClassItem> Items { get; set; }
public class SomeClassItem
{
public string Code { get; set; }
public string Location { get; set; }
public string Easting { get; set; }
public string Northing { get; set; }
public string WaterName { get; set; }
public string WfdCode { get; set; }
}
public SomeClassInput()
{
Items = new List<SomeClassItem>();
}
}
从 Action 返回的模型,可以包含默认数据 - 少量项目。
我正在使用 JSON 的自定义序列化设置,因此所有 PascalCase 属性名称都转换为 camelCase。
绑定非常简单(包装某种控制器以管理少量屏幕和动态加载视图):
this.model = ko.mapping.fromJS(modelJson);
ko.applyBindings(this.model, this.view.content[0]);
现在在视图中我有一张桌子:
<table class="table table-striped table-bordered" id="some-table"
data-swo-codes="@Url.Action("Codes", "Controller")"
>
<thead>
<tr>
<th>
[Actions]
</th>
<th>
Code
</th>
<th>
Location
</th>
<th>
Name of Water
</th>
<th>
WFD Code
</th>
</tr>
</thead>
<tbody data-bind="template: {name: 'rowTemplate', foreach: items}">
</tbody>
<tfoot>
<tr>
<td colspan="6">
<button class="btn" data-bind="click: table.addRow">Add new Storm Water Overflow</button>
</td>
</tr>
</tfoot>
</table>
<script type="text/html" id="rowTemplate">
<tr>
<td>
<button class="btn" data-bind="click: $parent.table.removeRow "><i class="icon-remove"></i></button>
<button class="btn" data-bind="click: $parent.table.moveUp, disable: ko.computed(function() { return $parent.table.moveUpEnabled.call($parent, $data); }, $parent) "><i class="icon-arrow-up"></i></button>
<button class="btn" data-bind="click: $parent.table.moveDown, disable: ko.computed(function() { return $parent.table.moveDownEnabled.call($parent, $data); }, $parent) "><i class="icon-arrow-down"></i></button>
</td>
<td>
<select data-bind="options: $parent.codes, optionsText: 'name', value: code, optionsCaption: 'Select Code...'"></select>
</td>
<td>
<label data-bind="visible: code, text: location" />
</td>
<td>
<label>E</label><label data-bind="visible: code, text: easting" />
<label>N</label><label data-bind="visible: code, text: northing" />
</td>
<td>
<label data-bind="visible: code, text: waterName" />
</td>
<td>
<label data-bind="visible: code, text: wfdCode" />
</td>
</tr>
</script>
这不是工作示例 - 所以标签可以是跨度或任何需要的。
$parent.table | table - 围绕表格包装所有操作,例如添加一行、删除、上下移动。这行得通。
只有一个单元格是可编辑的——代码。代码将是一个下拉菜单,由后台的一些 ajax 代码初始化,返回所有可能的代码和连接到项目的元数据 - 此调用在模型 ko.applyBindings 之前执行。 ajax 调用的结果看起来几乎像模型:
[ {
name: 'some_name_of_code',
code: 'GUID',
location: 'some_place',
easting: '435',
northing: '345',
waterName: 'some_name',
wfdCode: 'some_code'
}, {
//..
}]
当用户从代码下拉列表中选择一个项目时,所有属性都应该显示并映射到模型。 this.model.items[0].easting 将并且应该返回一个值。
所以当用户点击保存时,我可以打开模型并将其作为 JSON 发布到 MVC 操作。
更新
以防万一,因为我所有的淘汰赛视图模型都由 controller 管理,所以有一个标准。将模型发布回服务器的方式,负责它的片段:
save: function () {
var that = this,
model = ko.mapping.toJS(this.model);
delete model.help;
logger.log(this.id + ' SAVE event executing');
return $.ajax({
type: 'POST',
url: this.saveUri,
data: JSON.stringify(model),
contentType: 'application/json; charset=utf-8',
success: function() {
logger.log(that.id + ' SAVE event executed and finished with success, cleaning up dirty flag');
that.model.tracker().markCurrentStateAsClean();
}
});
}
结束更新
问题
如果不编写大量自定义函数来设置数据,我不确定如何实现我想要的——从动作返回的模型到视图模型,以及从视图上的内容到将被回发的模型到服务器。
任何帮助将不胜感激。
更新
结束更新
【问题讨论】:
-
你想达到什么目的?我迷路了...... Jsfiddle 展示问题所在会很有帮助。
-
jsfiddle 添加。我想将我在下拉列表中选择的内容映射到模型中的项目,以便我的通用保存方法可以处理保存。此外,我应该能够显示加载时从服务器传递的数据
标签: knockout.js