使用knockout.js跨列对数据绑定javascript关联数组

时间:2014-05-04 17:37:25

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

在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。

UPDATE1:

我已将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>

1 个答案:

答案 0 :(得分:0)

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

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

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>