Привязка DateTime к модели представления нокаута с помощью JavaScriptSerializer по умолчанию

Я только начал использовать knockout, и у меня возникли проблемы с сериализацией и десериализацией DateTime с помощью JavaScriptSerializer.

Я обновил модель подарков в Стиве koListEditor пример из своего блога для включения поля Modified DateTime:

public class GiftModel
{
    public string Title { get; set; }
    public double Price { get; set; }
    public DateTime Modified { get; set; }
}

Затем я обновил Index.aspx, включив в него новое поле:

<asp:Content ContentPlaceHolderID="MainContent" runat="server">
    <h1>Gift list editor</h1>

    <p>You have asked for <span data-bind="text: gifts().length">&nbsp;</span> gift(s)</p>

    <form class="giftListEditor">
        <table> 
            <tbody data-bind="template: { name: 'giftRowTemplate', foreach: gifts }"></tbody> 
        </table>

        <button data-bind="click: addGift">Add Gift</button>
        <button data-bind="enable: gifts().length > 0" type="submit">Submit</button>
    </form>

    <script type="text/html" id="giftRowTemplate"> 
        <tr> 
            <td>Gift name: <input class="required" data-bind="value: Title, uniqueName: true"/></td> 
            <td>Price: \$ <input class="required number" data-bind="value: Price, uniqueName: true"/></td> 
            <td>Modified:  <input class="required date" data-bind="value: Modified, uniqueName: true"/></td> 
            <td><a href="#" data-bind="click: function() { viewModel.removeGift($data) }">Delete</a></td> 
        </tr>
    </script>

    <script type="text/javascript">
        var initialData = <%= new JavaScriptSerializer().Serialize(Model) %>;
        var viewModel = { 
            gifts : ko.observableArray(initialData), 

            addGift: function () { 
                this.gifts.push({ Title: "", Price: "", Modified:"" }); 
            },

            removeGift: function (gift) { 
                this.gifts.remove(gift); 
            },

            save: function() { 
                ko.utils.postJson(location.href, { gifts: this.gifts }); 
            } 
        }; 

        ko.applyBindings(document.body, viewModel);
        $("form").validate({ submitHandler: function() { viewModel.save() } });
    </script> </asp:Content>

Однако, когда JavaScriptSerializer сериализует модель

var initialData = <%= new JavaScriptSerializer().Serialize(Model) %>;

Дата изменения выглядит следующим образом:

Проблема с датой и временем

Также при использовании UK Dates I.e. 01.02.2011 JavaScriptSerializer.Deserialize выдает следующее исключение:

01.02.2011 не является допустимым значением для DateTime.

Хотя у меня здесь две проблемы, главный вопрос: кто-нибудь успешно использовал knockout из MVC 2 и заставил JavaScriptSerializer работать с ДатаВремя? Я понимаю, что мог бы написать свой собственный JavaScriptSerializer, но я надеялся, что там есть готовое решение :)

Вот код обновленной версии koListEditor Стива Сандерсона:

Код на моем SkyDrive

Спасибо

Дэйв


person CraftyFella    schedule 25.01.2011    source источник
comment
Любой, кто просматривает вышеизложенное.. вы можете использовать JSON.net для отправки дат клиенту в любом формате, который вы хотите.. см. james.newtonking.com/archive/2009/02/20/   -  person CraftyFella    schedule 23.02.2011


Ответы (2)


Ну есть два варианта. Вы можете сделать простое исправление, имея назначенный объект модели представления, который хранит предварительно отформатированные значения даты и времени в виде строки. Это обычно то, что я делаю. Затем я могу попытаться проанализировать значение даты для проверки.

Другой вариант — реализовать пользовательскую привязку данных. Вы можете посмотреть, как это делается здесь. Это будет более элегантный подход. Хорошая вещь в этом подходе, вы можете затем создать код генерации пользовательского интерфейса при привязке, что позволит вам добавить средство выбора даты в пользовательский интерфейс в процессе.

person Sergei Golos    schedule 23.02.2011
comment
Хороший чувак... например, индивидуальный подход к привязке... Как я уже сказал другому чуваку... в конце концов я обнаружил, что JSON.net был самым простым решением... так как он позволял нам отправлять даты клиенту в любом виде формат который мы хотели.. - person CraftyFella; 23.02.2011
comment
Да, большой поклонник подхода кастомных креплений. Надеюсь, я не переусердствую в своем проекте, но это делает HTML таким чистым. - person Sergei Golos; 23.02.2011

Не элегантное решение, но оно работает:

data-bind="value: eval('new ' + Modified.slice(1,-1)), uniqueName: true"

Eval может быть проблемой безопасности в зависимости от контекста.

person Don Smith    schedule 10.02.2011
comment
В конце концов я нашел решение. Я использовал JSON.net, который позволяет вам указать свой собственный формат даты. james.newtonking.com/ archive/2009/02/20/ работает отлично.. - person CraftyFella; 15.02.2011