2014-12-17 2 views
0

Я работаю над web application, используя Asp.Net Mvc, в котором я использовал нокаут Js для извлечения и отправки данных в Html View, выполняя некоторую операцию над данными.Неверные значения из наблюдаемого массива нокаута

Для примера я следующие данные в моем массиве с именем datainput

Grade Type Volume Price 
A  Buy 1000 10 
A  Sell 1200 10 
B  Sell 100 100 

Я вычислительное массив, который таким образом, что при отображении на HTML странице он просто занимает одно неоспоримое значение класса и групп данных в рамках что оценка как

A 
Buy 1000 10 
Sell 1200 10 

B 
Sell 100 100 

Использовал выше функцию следующим образом

self.uniqueSelect = ko.dependentObservable(function() { 
      var Transactiontypes = ko.utils.arrayMap(self.datainput(), function (item) { return item.Grade }) 
      return ko.utils.arrayGetDistinctValues(Transactiontypes); 
     }); 

Я не думаю, что есть проблема с выше сценарий, не уверен, но, хотя я пошел вперед и использовать данные, полученные из приведенного выше сценария и попытались заполнить его HTML следующим образом

<!--ko foreach: uniqueSelect--> 

     <tr> 
      <td class="clientproductHeader" data-bind="text: $data"></td> 
      <td class="clientproductHeader" colspan="10"></td> 
     </tr> 


     <tbody data-bind="foreach: ko.observableArray($root.datainput()).extendsdistinct('Grade').index.Grade()[$data]"> 
<tr> 
<script type="text/html" id="read-template"> 

     <td data-bind="text: Type"></td> 
     <td data-bind="text: Volume"></td> 
     <td data-bind="text: (typeof Price() === 'number') ? Price().toFixed(2) : '' "></td>  

    </script> 
</tr> 

     </tbody> 
     <!--/ko--> 

    </table> 

выше сценарий для некоторых причины отображают повторяющиеся данные, например, если класс повторяется два раза, как в примере данных, он отображает одни и те же данные этого разряда два раза, и если он повторяется три раза, он отображает его три раза и так далее.

Я думал, что ошибка была с <!--ko foreach: uniqueSelect-->, потому что она просто зацикливает данные в зависимости от количества аналогичных оценок.

результатов на HTML странице, как

A 
    Buy 1000 10 
    Sell 1200 10 

B 
    Sell 100 100 

A 
    Buy 1000 10 
    Sell 1200 10 

В приведенных выше данных Grade A повторяются дважды, так что все данные с классом А повторяются два раза, где, как класс B имеет только один вход и так, это произошло только когда экран данных я получил enter image description here Понятия не имею, как бороться с этим

+0

Я бы сделал группировку с простым javascript, а затем использовал KO для рендеринга этой сгруппированной структуры данных. Более читабельна и менее логична в слое представления. Для получения рекомендаций по устранению неполадок посыпайте свой код с помощью console.log() и проверьте свои предположения, например. см., если 'uniqueSelect' содержит то, что вы ожидаете –

+0

Я сравнил демо-версию, подобную первоначальному подходу (http://jsfiddle.net/origineil/vnyymhmz/). Если возможно, я склоняюсь к массиву данных с одним проходом. – Origineil

+0

@Origineil jsfiddle кажется прекрасным, но мои данные поступают из базы данных, и когда я передаю datainput к функции, которую у вас есть, она не работает – DoIt

ответ

1

я прошел и написал версию, которая делает то, что я думаю, что вы пытаетесь достичь. Он использует метод, описанный Петерисом. See it in action.

Вы хотите, чтобы код просмотра был как можно более простым, а также будьте осторожны, чтобы вернуться в $root. Если вы уверены, что хотите сделать это с помощью фильтра, сделайте тот, который будет похож на группу, как показано ниже, а затем перебирайте каждую из своих записей/детей. Кроме того, старайтесь избегать объявления наблюдаемых в ваших представлениях.

Наконец, вы можете объединить groupByGrade() и getGrades() в одну функцию, которая возвращает объект с свойством для каждого из результатов. Это спасло бы цикл итерации.

Вид:

<tr> 
    <td class="clientproductHeader" data-bind="text: 'Grade ' + $data + ' (' + $root.log()[$data].length + ' trades)'"></td> 
    <td class="clientproductHeader" colspan="10"></td> 
</tr> 


<tbody data-bind="foreach: $root.log()[$data]"> 
    <tr> 
    <td data-bind="text: type"></td> 
    <td data-bind="text: volume"></td> 
    <td data-bind="text: (typeof price === 'number') ? price.toFixed(2) : '' "></td> 
    <td class="actioncells"> 

     <a class="btn btn-success" title="Edit" data-bind="click: $root.edit">Edit</a> 
    </td> 

    <td class="actioncells"> 
     <a class="btn btn-danger" title="Delete " data-bind="click: $root.remove">Delete</a> 
    </td> 
    </tr> 

</tbody> 
<!--/ko--> 

И JavaScript:

function testViewModel() { 

    // Underscore and Lo-dash both have a function to group 
    // an object by key. That's what you want. Here is a 
    // really simple version. 
    function groupByGrade(data) { 
    return data.reduce(function(last, next) { 
     if (last[next.grade]) { 
     last[next.grade].push(next); 
     } else { 
     last[next.grade] = [next]; 
     } 
     return last; 
    }, {}); 
    } 

    // Get a unique list of the grades in the data to iterate over 
    function getGrades(data) { 
    return data.reduce(function(last, next) { 
     return !!~last.indexOf(next.grade) ? last : last + next.grade; 
    }, '').split(''); 
    } 

    var rawData = [ 
    { 
     grade: 'A', 
     type: 'Buy', 
     volume: 1000, 
     price: 10 
    }, { 
     grade: 'A', 
     type: 'Sell', 
     volume: 1200, 
     price: 10 
    }, { 
     grade: 'B', 
     type: 'Sell', 
     volume: 100, 
     price: 100 
    } 
    ]; 

    console.log(getGrades(rawData)); 

    this.log = ko.observable(groupByGrade(rawData)); 
    this.grades = ko.observableArray(getGrades(rawData)); 
} 

ko.applyBindings(new testViewModel()); 

+0

, он возвратил некоторые неопределенные значения, когда я передал свой массив данных для функции gerGrades, например this.grades = ko.observableArray (getGrades (self. ввод данных())); – DoIt

+0

Можете ли вы привести пример массива? Еще лучше, можете ли вы разблокировать Plunker и поделиться ссылкой? Подсказка: вы можете использовать 'console.log (JSON.stringify (datainput))' – Joshua

Смежные вопросы