因此,标题是有点做作,但是这基本上是我想要完成的任务:
<ul data-bind="template: { name: 'ItemFormTemplate', foreach: Items }">
@foreach (var item in Model.Items)
{
Html.RenderPartial("_ItemForm", item);
}
</ul>
<script type="text/html" id="ItemFormTemplate">
@{ Html.RenderPartial("_ItemForm", new Item()); }
</script>
这里的想法是:
我想对表单
Item
是局部的,我想用相同部分的剃刀的的foreach和喂养淘汰赛模板两者。 (我不想重复HTML也可以建立只为淘汰赛特殊版本。)剃刀的foreach是后备的情况下,JavaScript被禁用或不支持。 形式应仍是可编辑和submittable(作为模型中的粘合剂将处理正确的POST数据),有或没有JavaScript。
当然,这意味着该字段名称都需要遵循类似的模式
Items[0].SomeField
。 部分将被强类型仅一个Item
,虽然(而不是IEnumerable<Item>
可以理解的是,这将不是真的有可能为淘汰赛模板,因为目前指数将只提供客户端。 我有我已经使用了一个解决办法:ko.bindingHandlers.prefixAndIndex = { init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { if (bindingContext.$index) { var prefix = ko.utils.unwrapObservable(valueAccessor()); var $element = $(element); $element.find('input,textarea,select').each(function () { var $this = $(this); var newId = prefix + '_' + bindingContext.$index() + '__' + $this.attr('id'); var newName = prefix + '[' + bindingContext.$index() + '].' + $this.attr('name'); $('label[for=' + $this.attr('id') + ']').attr('for', newId); $this.attr('id', newId); $this.attr('name', newName); }); } } };
这只是结合模板(的顶级元素
<li>
在这种情况下)和搜索和替换所有标识和名称以适当的前缀属性。 这似乎工作得很好,但任何批评或改进建议,欢迎。
说真的,我现在挣扎的唯一的事情是获得适当的前缀到部分当剃刀的foreach内。 通常,你会使用这一个解决for
,而不是foreach
,然后通过索引项而不是只是一个普通的项目,即:
@for (var i = 0; i < Model.Items.Count(); i++)
{
@Html.TextBoxFor(m => m.Items[i].SomeField)
}
但是,这并不使用部分时,因为一旦你进入部分,你仍然只是一个单一的处理工作Item
,断章取义。
所以,最迫切的问题是我怎么能仍然使用局部强类型Item
,但仍然有它知道任何指数目前的? 然后,除此之外,如何最好地减少重复或HTML和逻辑(增加代码重用)。 我在正确的轨道上我的思维上休息。 请问有什么可以改善或做的更好?
编辑
我应该指出, 最好我想保留,部分强类型和实际利用。 换句话说,我希望能够做@Html.TextBoxFor(m => m.SomeField)
而不是伪造它像@Html.TextBox("Items[" + iterator + "].SomeField")
如果我必须走这条路,这是一两件事,但我希望有一个更好的办法。
我想我也可以做线沿线的东西:
@Html.TextBox(prefix + "[" + iterator + "]." + Html.NameFor(m => m.SomeField))
然后通过prefix
和iterator
到部分。 那是在我没有处理硬编码值感更好,但它是一个很多额外的逻辑尤其是持续了部分与一群领域。 同样,希望有个更好的办法。