2011-08-13 8 views
8

Poszukuję najlepszego sposobu zainicjowania tablicy obnażalnych nokautów z niektórych danych serwera (ViewBag) i chcę, aby zawartość tablicy była typu javascript I zdefiniowałeś. Bez wymogu typu JS może po prostu użyć:Knockout JS inicjuje tablicę obserwowalną z danych serwera przy użyciu javascript typu

materialVarieties: ko.observableArray(@Html.Raw(Json.Encode(ViewBag.Materials))) 

ale mam również rodzaj materiału JS, który chcę użyć, więc mogę mieć pewne właściwości konkretnych extra viewmodel i funkcje tj:

var material = function(id, name) { 
    this.id = id; 
    this.name = name; 
    this.selected = ko.observable(false); 

    this.select = function() 
    { 
     jQuery.each(processViewModel.materials(), function(index, item) 
     { 
      item.selected(false); 
     }); 
     this.selected(true); 
     } 
} 

i wtedy konieczne staje inicjalizacji:

materialVarieties: ko.observableArray([new material(1, "Apricot"), ..... 

Obecnie zbudować ciąg z danych ViewBag a potem czynią to jako inicjatora tak:

@{ var items = string.Join(",", 
       ((IEnumerable<MaterialVariety>) ViewBag.Materials) 
          .Select(m => string.Format("new material({0}, {1})", 
             Json.Encode(m.Id), Json.Encode(m.Name)))); } 

var processViewModel = { 
    material: ko.observableArray([@Html.Raw(items)]) 

Ale zastanawiam się, czy jest bardziej przejrzysty sposób niż string.Join bit. Mógłbym to zawinąć w pomocnika. Co robisz?

+1

Dlaczego nie utworzyć metody rozszerzenia HtmlHelper? Weź ogólny argument i zwróć zakodowane wyjście. – Anuj

+0

@Anuj Tak, to było to, o czym myślałem ("Mógłbym je zawrzeć w Pomocniku"), musiałby również mieć ciąg reprezentujący typ JS. Problem pojawia się podczas opracowywania właściwości do użycia w konstruktorze JS (i wymaganej kolejności). Mogę odzwierciedlić ogólny argument, aby uzyskać właściwości, ale miałem nadzieję, że użyję moich modeli po stronie serwera (nie chcę innego zestawu maszyn po stronie serwera) i mają inne właściwości, których nie potrzebuję w moim JS. I nadal pozostawia mi problem z zamówieniem konstruktora ..... chyba że czegoś mi brakuje? –

Odpowiedz

15

Zazwyczaj najpierw serializuje się tablicę, a następnie mapuję ją, umieszczając ją w modelu widoku. Byłoby tak:

var originalVarieties = @Html.Raw(Json.Encode(ViewBag.Materials)) 

var processViewModel = { 
    materialVarieties: ko.observableArray(ko.utils.arrayMap(originalVarieties, function(variety) { 
     return new material(variety.id, variety.name); 
    })) 
} 

Wymaga niewielkiej ilości dodatkowego przetwarzania po stronie klienta, ale wydaje się czystszy niż tworzenie ciągów.

+0

ah, który wygląda dobrze. Jestem nowy w Knockout i nie wiedziałem o utils.arrayMap. Dziękuję Ci. –

+0

może po prostu użyć mapy jQuery, jak również przypuszczam ... –

+2

tak, nie ma nic specjalnego w ko.utils.arrayMap. Całkiem prosty kod. Mapa jQuery zrobiłaby to samo. –

Powiązane problemy