2013-07-24 27 views
12

Mam ten nokaut mapowania mojej tablicy retreived z połączenia ajax poniżej.Limit pętli foreach pętli

function InvoiceViewModel(data) { 
var self = this; 

self.survey = data; 

} 

Ajax połączeń

$.ajax({ 
    url: 'http://localhost:43043/api/damage', 
    type: 'GET', 
    headers: { 'Accept': 'application/json' }, 
    data: { 
     orderNumber: num, 
     category: cat 
    }, 
    success: 
      function (data) { 
       var usingRoutData = document.URL; 
       ko.applyBindings(new InvoiceViewModel(data)); 
      }, 

    error: function() { 
     alert('failure'); 
    } 

}); 

Mój Array

var test = { 
    Name: Blah, 
    Attributes: [ 
       {Name: Test, Type: Photo, Year:1988}, 
       {Name: Test, Type: Photo, Year:1988}, 
       {Name: Test, Type: Photo, Year:1988} 
       ] 
      }; 

Jak ja wiążące moich danych

<div id="invoiceBodyWrapper"> 
<div data-bind="template: { name: 'invoice-template', foreach: surveys }"> 
</div> 

<div class="invoiceWrapper"> 
    </div> 
    <div id="completePictureWrapper" data-bind="template: { name: 'photo-template',  foreach: new Array(Attributes) }"></div> 

</div> 
</script> 

<script type="text/html" id="photo-template"> 
<!-- ko if: classification === 'photo' --> 
<div id="pictureWrappers"> 
    <img class="img" data-bind="attr: { src: 'http://myimagepath/download/full/' + $index()+1 }" /> 
</div> 
<!-- /ko --> 
</script> 
    <script src="~/Scripts/DamageInvoiceCreation.js"></script> 

Potrzebuję sposobu na ograniczenie moich atrybutów pętli foreach, aby pokazać tylko 2 z 3 atrybutów. Znalazłem tylko kilka rzeczy, jak to zrobić i wydają się bardzo skomplikowane. Nie mogę sobie wyobrazić, że nie ma prostego sposobu na zrobienie tego w nokaucie.

+0

Nie ma pętli w swoim poście. W jaki sposób wiążesz swój pogląd? – Romoku

+1

Czy widziałeś [Knockout.js - dynamiczne kolumny, ale limit do maksymalnie 5 dla każdego wiersza] (http://stackoverflow.com/q/7669946/580951) – Romoku

+0

@Romoku dużo się nauczyć w tym pytaniu, ale jest zdecydowanie odpowiedni kod. Dobry link! –

Odpowiedz

0

można ograniczyć pętli w ten sposób:

for(var i=0;i<data.length;i++){ 
    if(i>1){ 
     return false; 
    } 
} 
+0

możesz dodać do tego jakiś kontekst. Również nie jest to cała tablica, którą chciałbym ograniczyć tylko do tablicy podrzędnej. – EntryLevel

+1

Wykonaj to tylko dla pod-tablicy. zastąp dane danymi. Atrybuty –

7

Jeśli zawsze mają 3 atrybuty i zawsze chce tylko pokazać 2 z nich, nie trzeba ich foreach, dokładnie.

Istnieje jednak specjalna zmienna kontekstu wiążącego $index(), która pozwoli Ci wykonać podstawowe ukrywanie, chociaż nie uniemożliwi renderowania. Ponieważ indeks $ wynosi 0, warunkiem jest $index() < 2. Jak zauważa Andrey w komentarzach, $index is an observable, więc musisz wywołać go w nawiasie jako metodę, lub porównania nie zrobią tego, czego się spodziewasz (porównasz int do funkcji).

<ul data-bind="foreach: survey.Attributes"> 
    <li data-bind="visible: $index() < 2"> 
     Name: <span data-bind="text: Name"> </span><br/> 
     Type: <span data-bind="text: Type"> </span><br/> 
     Year: <span data-bind="text: Year"> </span><br/> 
    </li> 
</ul> 

Jeśli chcesz ogólny ogranicznik w pętli foreach, masz rację, to nie jest proste. Będziesz musiał wykonać custom binding.

Innym rozwiązaniem, które można rozważyć, jest wstępne przetwarzanie danych w widoku modelu. Po ustawieniu this.survey = data; możesz usunąć dowolny z atrybutów, których nie chcesz wyświetlać w tym momencie.

Edycja: Widzę z Twojej edycji, że wiesz o elementach psuedo z ko: if. Całkowicie o nich zapomniałem, ale można łatwo użyć jednego, aby zapobiec wyświetlaniu elementów szablonu poza określonym indeksem. foreach nadal oceniałoby to, co można zaobserwować, które nie powinno samo w sobie mieć dużego obciążenia.

+1

Myślę, że masz na myśli '$ index()'. '$ index <3' zawsze zwróci false http://jsfiddle.net/aDahT/1087/ –

+0

Masz rację oczywiście, @AndreyNelubin, zaktualizował odpowiedź. –

+0

To zdecydowanie jedno z najładniejszych rozwiązań tego problemu, jeśli chcesz pokazać tylko 2 atrybuty, powinieneś użyć <2 [0 to także liczba :)] –

5

tablice JavaScript obejmują doskonałą slice metodę, która powinna wypełnić swoje potrzeby ładnie:

template: { name: 'photo-template', foreach: Attributes.slice(0,2) } 

Ale jak @ Patrick-M wspomniano, nie trzeba pętlę:

template: { name: 'photo-template', data: Attributes[0] } 
template: { name: 'photo-template', data: Attributes[1] } 

Moja Repeat Wiązanie zawiera opcję ograniczenia liczby powtórzeń:

<div data-bind="repeat: { foreach: Attributes, count: 2 }" 
     data-repeat-bind="template: { name: 'photo-template', data: $item() }"> 
</div> 
0

Rozwiązałem podobny problem, przesuwając podzbiór oryginalnych elementów tablicy do innej tablicy w moim module viewmodel, a następnie łącząc się z tablicą podzbiorów.

+0

Myślę, że czasami ludzie stają się "zbyt ambitni" z KO i rzucają zbyt dużo JS w HTML. To całkiem logiczne rozwiązanie. Nie zrozumcie mnie źle, nie ma nic złego w KO, to świetna biblioteka UI. –

3

Można tworzyć komputerowej z ograniczoną limitem tablicy:

var limited = ko.computed(function() { 
    return Attributes.slice(0, limit); 
}); 

Następnie wszystko co musisz zrobić, aby foreach ograniczona. Można nawet dodać somekind „więcej” elementu:

<!-- ko if: Attributes().length > limit --> 
    <div class="more">...</div>   
<!--/ko--> 

Mam nadzieję, że będzie to pomocne dla kolejnych pokoleń;)