30 votes

Gestion des dates avec Asp.Net MVC et KnockoutJS

J'ai récemment commencé à travailler avec KnockoutJs et rapidement réalisé à l'aide de la valeur par défaut Json(myModelWithADate) a entraîné le défaut encodage json de \/Date(-62135578800000)\/ Avec un peu de recherche, j'ai trouve quatre façons de gérer l'affichage de mes dates dans les éléments du dom.

1) Créer une liaison qui assure la conversion de l'Json date pour le format que vous désirez

ko.bindingHandlers.date = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        var jsonDate = valueAccessor();
        var value = new Date(parseInt(jsonDate.substr(6)));
        var ret = value.getMonth() + 1 + "/" + value.getDate() + "/" + value.getFullYear();
        element.innerHTML = ret;
    },
    update: function(element, valueAccessor, allBindingsAccessor, viewModel) {

    }
};

L'utilisation de la

<td data-bind="date: DueDate">
</td>

2) le Retour de "cordes" à partir de votre Contrôleur

return Json(new {MyDate = DateTime.Now.ToShortDateString()});

3) Utiliser le JSON.NET pour spécifier un format de Date / Heure vu à james.newtonking.com

Exemple

string isoJson = JsonConvert.SerializeObject(entry, new IsoDateTimeConverter());
// {"Details":"Application started.","LogDate":"2009-02-15T00:00:00Z"}

4) l'utilisation de JSON.analyser pour gérer vos dates comme on le voit dans cette stackoverflow réponse.

JSON.parse(jsonText, function(key, value) {
    // Check for the /Date(x)/ pattern
    var match = /\/Date\((\d+)\)\//.exec(value);
    if (match) {
        var date = new Date(+match[1]); // Convert the ticks to a Date object
        return humanReadable(date); // Format the date how you want it
    }

    // Not a date, so return the original value
    return value;
});

Ils semblent tous fonctionner, mais j'ai encore de la difficulté avec laquelle on se sent "à droite". Droit maintenant, mon intestin est d'aller avec un mélange avec de la liaison et le retour de chaînes. Comme j'ai pu le voir moi-même l'extension de la liaison à la poignée d'entrée avec jQuery UI datepicker contrôles.

Est-il une pratique acceptée lors de la manipulation de l'affichage des dates ou d'autres types tels que la monnaie? Est-il une autre option, je suis absent qui permet de résoudre ce problème?

13voto

Paul Tyng Points 5203

Personnellement, je pense que l' JSON.NET la solution est le meilleur tout simplement parce qu'il impose de moins en moins sur le client. Toutes les autres solutions requièrent client supplémentaire ou d'analyse supplémentaires code client.

J'ai basculé à l'aide de JSON.NET pour l'ensemble de mes ASP .NET code qui utilise JSON en raison de son beaucoup plus personnalisable de la bibliothèque.

Par exemple, j'ai dû mettre en place des données JSON dans MVC qui est conforme à Google Chart API (utilisé en combinaison avec knock-out pour la pagination, etc.) et la valeur par défaut JavascriptSerializer ne peut tout simplement pas le faire.

En plus avec JSON.NET vous pouvez le personnaliser en fait cracher plein Knockout modèles de vue de sorte que vous n'avez même pas besoin d'utiliser le plugin de cartographie.

J'ai écrit un échantillon bibliothèque appelée FluentJson.NET qui permet de faire des choses en Rasoir comme:

var viewModel = @JsonObject.Create()
    .AddProperty("name", "value")
    .AddObservable("knockoutProperty", 123)

Et obtenez:

var viewModel = {"name":"value","knockoutProperty":ko.observable(123)}

Si vous pouvez obtenir un knock-out modèle de vue, sans côté client à sauter à travers des cerceaux.

Vous pouvez facilement étendre quelque chose comme ça pour manipuler les valeurs de date toutefois vous préférez.

6voto

Andres Toro Points 61

Je suggérerais une approche intermédiaire par ko.mapping.fromJS( data, mapping ) cela vous permettrait de personnaliser même avec un objet défini par l'utilisateur.

 var $data = { _ID : '1', _Created : someDate };  
var $mapping = {
    '_Created' : {
       update: function (options) {
           return convertdata( options.data );
       }
    }
}
var viewDataModel = ko.mapping( data, mapping );  
ko.applyBindings( viewDataModel );
 

Le paramètre de mappage vous permet de gérer facilement les modifications et peut également être facilement exploité avec des tableaux.

5voto

Ajay Kelkar Points 1119

La meilleure façon de gérer les dates en knockoutjs est d'utiliser moment de bibliothèque et de gérer les dates comme patron. Vous pouvez facilement régler les dates comme /Date(-62135578800000)/. Pas besoin de se soucier de la façon dont votre sérialiser date dans le contrôleur.

Approche 1 : Directement dans la vue:

Disons que votre knock-out modèle obtient cette date dans une observable appelé sentDate et maintenant il a de la valeur /Date(-62135578800000)/. Pour la lier à la vue que vous pouvez faire :

<p><label>Date</label>: <span data-bind="moment(sentDate).format('MM/DD/YYYY')"></span></p>

Approche 2 : En liaison personnalisée

ko.bindingHandlers.date = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        var jsonDate = valueAccessor();     
        var ret = moment(jsonDate).format('MM/DD/YYYY');
        element.innerHTML = ret;
    },
    update: function(element, valueAccessor, allBindingsAccessor, viewModel) {

    }
};

L'utilisation de la même façon que vous l'avait dit :

<td data-bind="date: sentDate">
</td>

momentjs prend en charge beaucoup de formats horaires et les fonctions de l'utilitaire sur les dates.

2voto

photo_tom Points 4160

J'utilise le code suivant pour générer des chaînes de date courtes. Je l'utilise pour mes chaînes de date et jQueryUi Date Picker.

 class T
    {
        public DateTime d { get; set; }
    }

static void Main(string[] args)
    {
        var k = new T { d = DateTime.Now };

        var formatter = new IsoDateTimeConverter();
        formatter.DateTimeFormat = "d";
        var s = JsonConvert.SerializeObject(k, formatter);
    }
 

Cela génère le JSON suivant

 "{"d":"4/21/2012"}"
 

Il en résulte un code JavaScript propre pour moi.

2voto

povilasp Points 1600

Je viens de poser cette question parce que nous avons également commencé à utiliser knockout.js sur notre application MVC3. Étant donné que nous avons déjà jQuery datepicker et que nous devons formater les dates différemment selon les paramètres régionaux (le portail a différentes langues et différents formats sont présentés par langue), alors peut-être que ce mélange d'exigences technologiques se pose ailleurs et sera utile:

 var jsDateFormat = "@CultureHelper.JsDateFormat"; // can be something like yy-mm-dd

//...

 ko.bindingHandlers.date = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        var value = valueAccessor();
        if (value != null) {
            var jsonDate = new Date(parseInt(valueAccessor().substr(6)));
            element.innerHTML = jQuery.datepicker.formatDate(jsDateFormat, jsonDate);
        }
    },
    update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
    }
};
 

Et dans la vue alors par exemple:

 <p><label>Date</label>: <span data-bind="date: SentDate"></span></p>
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X