27 votes

Knockout.js : format d'entrée de l'heure et restriction de valeur

Lorsque je lie des données numériques dans mon modèle de vue en utilisant knockout, elles s'affichent correctement mais changent le type de données en chaîne si l'utilisateur change la valeur de la balise d'entrée. Le problème de la soumission d'une chaîne est que le serveur s'attend à une valeur numérique sans qu'aucune conversion implicite ne soit disponible.

Y a-t-il un moyen de dire à knockout de conserver le type de données de la valeur de la propriété d'origine ?

Mon exemple de code qui fait correspondre les noms des modèles de vue aux noms des balises d'entrée. J'utilise un knockout discret pour faire les liaisons, ce qui fonctionne bien.

// Bind the first object returned to the first view model object
// FNS is the namespace, VM is the view model
FNS.VM.Items[0] = ko.mapping.fromJS(data.Items[0]);

// For each property found, find the matching input and bind it
$.each(FNS.VM.Items[0], function (indexInArray, valueOfElement) {
    var attrName = indexInArray;
    var attrValue;
    if (typeof valueOfElement == "function")
        attrValue = valueOfElement();
    else
        attrValue = valueOfElement;

    var a = $('input[name="' + attrName + '"][type="checkbox"]');
    if (a.length)
        a.dataBind({ checked: 'VM.Items[0].' + attrName });

    var b = $('input[name="' + attrName + '"][type="radio"]');
    if (b.length)
        b.dataBind({ checked: 'VM.Items[0].' + attrName });

    var c = $('input[name="' + attrName + '"][type="text"]');
    if (c.length)
        c.dataBind({ value: 'VM.Items[0].' + attrName });
});
ko.applyBindings(FNS);

45voto

RP Niemeyer Points 81663

Voici un fil de discussion avec quelques techniques différentes pour garder la valeur numérique : https://groups.google.com/d/topic/knockoutjs/SPrzcgddoY4/discussion

Une option est de pousser cette préoccupation dans votre modèle de vue et de créer une numericObservable à utiliser à la place d'un observable normal. Cela pourrait ressembler à :

ko.numericObservable = function(initialValue) {
    var _actual = ko.observable(initialValue);

    var result = ko.dependentObservable({
        read: function() {
            return _actual();
        },
        write: function(newValue) {
            var parsedValue = parseFloat(newValue);
            _actual(isNaN(parsedValue) ? newValue : parsedValue);
        }
    });

    return result;
};

Un échantillon : http://jsfiddle.net/rniemeyer/RJbdS/

Une autre option consiste à gérer cette situation avec une liaison personnalisée. Au lieu d'utiliser la méthode value vous pouvez définir une numericValue et l'utiliser à la place. Cela pourrait ressembler à ça :

ko.bindingHandlers.numericValue = {
    init : function(element, valueAccessor, allBindings, data, context) {
        var interceptor = ko.computed({
            read: function() {
                return ko.unwrap(valueAccessor());
            },
            write: function(value) {
                if (!isNaN(value)) {
                    valueAccessor()(parseFloat(value));
                }                
            },
            disposeWhenNodeIsRemoved: element 
        });

        ko.applyBindingsToNode(element, { value: interceptor }, context);
    }
};

Un échantillon : http://jsfiddle.net/rniemeyer/wtZ9X/

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