Razor 剔除绑定动态类型

Razor 剔除绑定动态类型,razor,knockout.js,knockout-mapping-plugin,Razor,Knockout.js,Knockout Mapping Plugin,我在MVC中有一个名为实体的模型,它包含属性,这些属性的值可以是三种属性之一。单位、下拉选择或本机类型(int、string、datetime等)。Unit和DropDownSelection非常简单,但它们的显示方式不同于本机类型(DropDownSelection->DropDown,native->Input,Unit->Input+DropDown) 我个人知道基于属性[0]。DataType,但如何将该信息适当地传递给Knockout,以便它在选择控件中显示DropDownSelect

我在MVC中有一个名为
实体
的模型,它包含
属性
,这些属性的值可以是三种属性之一。单位、下拉选择或本机类型(int、string、datetime等)。Unit和DropDownSelection非常简单,但它们的显示方式不同于本机类型(DropDownSelection->DropDown,native->Input,Unit->Input+DropDown)

我个人知道基于属性[0]。DataType,但如何将该信息适当地传递给Knockout,以便它在选择控件中显示DropDownSelections,在输入中显示本机类型,等等

当前视图

@model List<NMBS.EntityModels.Entity>

@* Page Content *@
<h1><span class="entity-type" data-bind="text: $data[0].EntityType"></span></h1>
<a data-bind="attr: { href: '/Entity/Create?EntityType=' + $data[0].EntityType() }" class="ignore">New</a>
<form>
    <table>
        <thead>
            <tr data-bind="template: { name: 'HeaderRowTemplate', foreach: $data[0].Properties }">
                <td data-bind="text: Name, visible: SummaryProperty"></td>
            </tr>
        </thead>
        <tbody data-bind="template: { name: 'DataRowTemplate', foreach: $data }">

        </tbody>
    </table>
</form>

@* Templates *@
<script id="HeaderRowTemplate" type="text/html">
    <td data-bind="text: Name, visible: SummaryProperty"></td>
</script>

<script id="DataRowTemplate" type="text/html">
    <tr data-bind="template: { name: 'DataItemTemplate', foreach: Properties }"></tr>
</script>

<script id="DataItemTemplate" type="text/html">
    <td data-bind="text: Value.ValueAsString, visible: SummaryProperty"></td>
</script>

@* Scripts *@
<script type="text/javascript">
    function ApplyBindings() {
        var data = @Html.Raw(new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(Model)),
            viewModel = ko.mapping.fromJS(data);
        ko.applyBindings(viewModel);
    }
    ApplyBindings();
</script>

问题:如何将值(即实体[I].Property[I].Value)数据绑定到正确的Html控件?有没有一种方法可以显式或隐式地告诉它为数据类型(实体[i].Properties[i].DataType)的某些值使用特定的模板?

我想说,您需要考虑编写自己的自定义绑定处理程序。

请注意,即使是data bind=“text:fooVar”也只是一个预定义的绑定处理程序,您始终可以使用自己的自定义绑定处理程序扩展knockout

在你的情况下,我将采取以下路线:

首先,重新定义标记以适应我们将要编写的处理程序:

<script id="DataItemTemplate" type="text/html">
    <td data-bind="visible: SummaryProperty">
        <label data-bind="text: Value.ValueAsString" />
        <input data-bind="customFormControl: Value" />
    </td>
</script>
关键是要了解更多关于这些参数的信息,这些参数是knockout返回给您的。一旦您理解了BindingHandler,您就会意识到您需要通过敲除完成的任何事情都是可以完成的,并且上下文总是可用的


祝你好运。

好的,我明天回去工作时再调查这件事。谢谢你的指导!
public Int32 ID { get; set; }
public String Name { get; set; }
public String DataType { get; set; }
public Boolean Required { get; set; }
public Boolean OnlyOne { get; set; }
public Boolean ForceNew { get; set; }
public dynamic Value { get; set; }
public String ValueAsString { get; set; }
public Boolean SummaryProperty { get; set; }
<script id="DataItemTemplate" type="text/html">
    <td data-bind="visible: SummaryProperty">
        <label data-bind="text: Value.ValueAsString" />
        <input data-bind="customFormControl: Value" />
    </td>
</script>
ko.bindingHandlers.customFormControl = {
    init: function ( element, valueAccessor, allBindings, viewModel, bindingContext ) {
        var val = valueAccessor(),
            dataType = bindingContext.$data.DataType;
        if ( dataType == 'Unit' ) {
            // define and replace 'element'
        } else if ( dataType == 'DropDownSelection') {
            // define and replace 'element'
        } else { 
            // control is already an input, so this shouldn't need any work
        }
    }, update: function ( element, valueAccessor, allBindings, viewModel, bindingContext ) {
        // do as you wish when the values are updated.
    }
}