2013-05-02 13 views
5

Używam knockout.js z wtyczką do mapowania. Dostaję trochę danych json i za pomocą wtyczki mapującej zamieniam ją na mój html.Knockout.js, wtyczka mapowania i moment.js - formatowanie/mapowanie dat jsonów

W danych json jest data sformatowana w json, którą muszę odwzorować w html za pomocą wtyczki mapowania. Czy można użyć pliku moment.js do sformatowania daty, a następnie zezwolić wtyczce mapowania na mapowanie jej do html? Jak mogę uzyskać datę json, sformatować ją do czytelnej daty i zmapować ją do html?

// Here is my json formatted date 
"DueDate":"\/Date(1362124800000)\/" 

// Here's my data model 
var viewModel; 
$.getJSON('/myJsonData', function (data) { 
    viewModel = ko.mapping.fromJS(data); 
    ko.applyBindings(viewModel); 

// moment.js format date from json - how can this be passed to the ko.mapping? 
    var mo = moment("\/Date(1362124800000)\/").format("MMM Do YY"); 
}); 

Odpowiedz

7

Oto alternatywna odpowiedź, że wykorzystuje custom binding. Go używać w widoku tak:

<span data-bind="textualDate: DueDate"></span> 

Kod zwyczaj wiązania jest tak:

ko.bindingHandlers.textualDate = { 
    update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     var valueUnwrapped = ko.utils.unwrapObservable(valueAccessor()); 
     var textContent = moment(valueUnwrapped).format("MMM Do YY"); 
     ko.bindingHandlers.text.update(element, function() { return textContent; }); 
    } 
}; 

Jest to wygodne, bo można to wykorzystać wiążące dla wszystkich Data obserwabli, nie tylko DueDate. Na przykład, załóżmy, że Twój model zostanie rozszerzony o innych terminach, łatwo można to zrobić bez konieczności modyfikowania widoku modelu:

<span data-bind="textualDate: StartDate"></span> 
<span data-bind="textualDate: RevisedDate"></span> 
<span data-bind="textualDate: DueDate"></span> 
<span data-bind="textualDate: WeWillGetSuedPassedThisDueDate"></span> 

Możesz sprawdzić this jsfiddle na demo roboczej.

+0

Za pomocą opcji odwzorowania można również zastosować tę samą transformację do wielu właściwości. Tak, niestandardowe powiązanie może być wygodne, ale musisz także pamiętać o jego użyciu. Jeśli daty są ustalone w całym interfejsie, lepiej jest dokonać konwersji z góry. W każdym razie twoje rozwiązanie konwertuje się w locie, więc jeśli OP chce wyświetlić 10 różnych miejsc, to 10 razy go przekonwertuje, podczas gdy wtyczka mapowania wykona tylko jedną konwersję. – nemesv

+0

@neesv Prawda. Odpowiedzi są różnymi rozwiązaniami, odpowiednimi do różnych sytuacji. – Jeroen

+1

Skończyło się na tym rozwiązaniu, ponieważ elastyczność ma największy sens dla projektu, w którym jest używana. Dzięki. – simple

4

Metoda mapping.fromJS przyjmuje obiekt opcji odwzorowania w drugim argumencie.

Możesz podać tam funkcję tworzenia (Customizing object construction using “create”) dla DueDate gdzie można zrobić konwersję date:

var data = { 
    "DueDate": "\/Date(1362124800000)\/" 
} 
var mappingOptions = { 
    DueDate: { 
     create: function (options) { 
      return moment(options.data).format("MMM Do YY"); 
     } 
    } 
}; 
viewModel = ko.mapping.fromJS(data, mappingOptions); 

Demo JSFiddle.