【问题标题】:knockout Binding Dynamic Types淘汰赛绑定动态类型
【发布时间】:2014-01-17 16:11:06
【问题描述】:

我在 MVC 中有一个名为 Entity 的模型,其中包含 Properties 并且这些属性的值可以是三件事之一。 Unit、DropDownSelection 或本机类型(int、string、datetime 等)。 Unit 和 DropDownSelection 非常简单,但它们的显示方式与原生类型不同(DropDownSelection -> DropDown、Native -> Input、Unit -> Input + DropDown)。

我个人基于 Property[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>

实体属性

public Int32 ID { get; set; }
public String EntityType { get; set; }
public Int32? ParentID { get; set; }
public Int32? PropertyValueID { get; set; }
public List<Property> Properties { get; set; }
public Entities Children { get; set; }
public Boolean IsValueEntity { get; set; }

物业属性

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; }

问题:如何将数据绑定值(即 Entity[i].Property[i].Value)绑定到正确的 Html 控件?有没有办法显式或隐式告诉它为 DataType (Entity[i].Properties[i].DataType) 的某些值使用特定模板?

【问题讨论】:

    标签: razor knockout.js knockout-mapping-plugin


    【解决方案1】:

    我想说您需要考虑编写自己的自定义绑定处理程序。 http://knockoutjs.com/documentation/custom-bindings.html

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

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

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

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

    其次,我们定义我们的处理程序。在这种情况下,我选择针对您的 DataType 属性进行测试,然后将子元素添加到您的表格单元格中。

    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.
        }
    }
    

    关键是要更多地了解淘汰赛向您抛出的这些参数。一旦您了解了 bindingHandlers,您就会意识到您需要通过 Knockout 执行的任何操作都可以完成,并且上下文始终可用。

    祝你好运。

    【讨论】:

    • 好的,我明天回去工作时会研究一下。感谢您的指导!
    猜你喜欢
    • 2013-01-09
    • 2013-03-06
    • 2019-01-14
    • 2013-02-04
    • 2013-11-22
    • 1970-01-01
    • 2013-10-31
    • 2013-08-14
    • 1970-01-01
    相关资源
    最近更新 更多