【问题标题】:Use knockout.js to data-bind javascript associative array across columns使用 knockout.js 跨列数据绑定 javascript 关联数组
【发布时间】:2014-06-20 23:33:35
【问题描述】:

在 C# DestopModel.cs 中,我们定义了一个 DesktopViewModel,其中包含许多设计。

public class DesktopViewModel
{
        public Guid Id { get; set; }              
        public List<DesktopDesignViewModel> Designs { get; set; }
        // ...
}

在我们的 script.cshtml 中,我们已将 DesktopViewModel 转换为淘汰视图模型 vew ko.mapping。 我们还有一个 DesignScore 函数,它进行一些计算并返回一组分数 针对多个类别的每个设计。

@model DesktopViewModel
<script type="text/javascript">

    var Desktop = {

        ViewModel: null,

        Initialize: function () {
            // create knockout model
            Desktop.ViewModel = ko.mapping.fromJS(@Html.Raw(Json.Encode(Model)));

            // ...

            this.ViewModel.DesignScore = function (design) {
                return ko.computed(function () {

                    var ClimateChange = 0;
                    var OceanAcidification = 0;
                    var OzoneDepletion = 0;
                    var BiogeochemicalCycles = 0;
                    var FreshWaterUse = 0;
                    var ChangeInLandUse = 0;
                    var BiodiversityLoss = 0;
                    var ChemicalPollution = 0;
                    var AtmosphericAerosols = 0;

                    // ... some calculations

                    return {
                        "ClimateChange": ClimateChange,
                        "OceanAcidification": OceanAcidification,
                        "OzoneDepletion": OzoneDepletion,
                        "BiogeochemicalCycles": BiogeochemicalCycles,
                        "FreshWaterUse": FreshWaterUse,
                        "ChangeInLandUse": ChangeInLandUse,
                        "BiodiversityLoss": BiodiversityLoss,
                        "ChemicalPollution": ChemicalPollution,
                        "AtmosphericAerosols": AtmosphericAerosols
                    };
                });
            }
        }
    }
</script>

在我们的 view.cshtml 中,我试图在表格中显示结果。

                        des1    des2    des3
=================================================
Climate Change          1560    936     3588
Ocean Acidification     1560    936     3588
Ozone Depletion         0.1     0.2     0.3
...

这是我目前对结果进行数据绑定的方式:

<table>
    <thead>
        <tr>
            <th class="col-md-2 text-center">&nbsp;</th>
            <!-- ko foreach: Designs -->
            <th class="text-center">
                <h5 data-bind="text: Name"></h5>
            </th>
            <!-- /ko -->
        </tr>
    </thead>
    <tbody>
        <tr class="top-border-row">
            <td class="text-center">
                <h4>Climate Change</h4>
            </td>
            <!-- ko foreach: { data: $root.Designs, as: 'design' } -->
            <td class="text-center">                                                                
                <h4 data-bind="text: $root.DesignScore(design)().ClimateChange"></h4>
            </td>
            <!-- /ko -->                            
        </tr>

        <tr class="top-border-row">
            <td class="text-center">
                <h4>Ocean Acidification</h4>
            </td>
            <!-- ko foreach: { data: $root.Designs, as: 'design' } -->
            <td class="text-center">                                                                
                <h4 data-bind="text: $root.DesignScore(design)().OceanAcidification"></h4>
            </td>
            <!-- /ko -->                            
        </tr>

        // ...                            

    </tbody>
</table>

现在,我正在迭代每个类别的每个设计,并在我的数据绑定中调用 DesignScore 九次,即使对 DesignScore 函数的一次调用将返回设计的所有类别的所有结果。

问题:有没有一种方法可以遍历每个设计一次,然后将各个类别的结果数据绑定到一列中? HTML 只有一个 tr 元素,但没有一个 tc 的列。

更新1:

我已将 DesignScore 函数拆分为单独的函数,并将每个函数的结果数据绑定到一个剔除模板中。生成的表格不过是一列。

输出:

des1  des2  des3
==================

1560 (ie. des1's Climate Change)

0.1  (ie. des1's Ozone Depleition)

3900.7 (ie. des2's Climate Change)

0.2

3588.6

0.3

代码:

<table>
<thead>
    <tr>
        <th class="col-md-2 text-center">&nbsp;</th>
        <!-- ko foreach: Designs -->
        <th class="text-center">
            <h5 data-bind="text: Name"></h5>
        </th>
        <!-- /ko -->
    </tr>
</thead> 
<tbody data-bind="template: { name: 'impact-category-template', foreach: $root.Designs, as: 'design' }"></tbody>
</table>

<script type="text/html" id="impact-category-template">    
      <tr>
          <td class="text-center"> 
              <h4 data-bind="text: $root.ClimateChange(design)"></h4>
          </td>
      </tr>
      <tr>
          <td class="text-center"> 
                  <h4 data-bind="text: $root.OzoneDepletion(design)"></h4>
          </td>
      </tr>
</script>

【问题讨论】:

    标签: javascript asp.net-mvc-4 knockout.js


    【解决方案1】:

    这真的不应该那么难。我没有完全掌握您的数据模型,但我会尝试将每一行建模为一个对象并使用模板来呈现它。尽可能简化。

    至于计算,每个类别是否相似?如果计算一次,我认为不需要计算。

    function DesktopDesignViewModel() {
      var self = this;
      self.categoryName= ko.observable();
      self.dest1= ko.observable();
      self.dest2= ko.observable();
      self.dest3= ko.observable();
      //may be used as constructor to fill in observables
      self.superCalc = function(){}; 
    }
    
    
    <script id="resultsTemplate" type="text/html">
       <tr>
           <td data-bind="text: categoryName"></td>
           <td data-bind="text: dest1"></td>
           <td data-bind="text: dest2"></td>
           <td data-bind="text: dest3"></td>
       </tr>
    </script>
    
    <table>
      <thead>
         <tr>
           <th>Name</th>
           <th>Dest1</th>
           <th>Dest2</th>
           <th>Dest3</th>
        </tr>
        </thead>
          <tbody data-bind="template: { name: 'resultsTemplate', foreach: Designs}"></tbody>
    </table>
    

    【讨论】:

    • 感谢您的回复。我不确定您建议的解决方案如何映射到我的数据模型。一方面,您的 dest1、dest2 和 dest3 字段,如果它们对应于我上面的 des1、des2、des3,这些是设计名称,它们对于每个设计都是动态的。 DesignScore() 函数返回一个设计(我们传入)的九个类别的分数集。它返回一个 ko.computed 值,因为它依赖于其他 ko.computed observables。而且我没有看到在绑定中使用 DesignScore() 的返回值的解决方案。
    • 看完knockout文档后,使用模板可能是我代码冗余问题的解决方案,我可能要打破现有的DesignScore(我没有设计数据模型),让ClimateChange ,OceanAcidification ...等,是ViewModel的独立函数,而不是通过单个DesignScore函数将所有内容作为javascript关联数组返回。然后我可以尝试分别绑定每个类别的每个单独的 DesignScore 函数。
    • 我试图分解我的 DesignScore 函数,并像在 UPDATE1 中一样应用剔除模板。但是当我遍历我的设计(每个设计应该占据一列)时,我的输出只会堆叠到一列。所以还是不行。
    • 当您查看源代码时,它是否具有正确的值,只是在错误的位置?
    • 是正确的值,但我不知道如何以与 OP 中相同的方式格式化值,因为模板中带有任何 tr 元素的设计上的 foreach 绑定会自动将设计和相关影响逐行堆叠在一起。
    猜你喜欢
    • 2012-03-21
    • 2013-01-14
    • 1970-01-01
    • 2015-03-28
    • 2013-01-13
    • 1970-01-01
    • 1970-01-01
    • 2021-08-03
    • 2023-03-15
    相关资源
    最近更新 更多