webentwicklung-frage-antwort-db.com.de

geben Sie am Knockout nur einen numerischen Typ ein

ich habe viele Tutorials gelesen, weiß aber nicht, wie das geht, das ist der Input

input(type="text",name="price",id="price"data-bind="text: price,valueUpdate:['afterkeydown','propertychange','input']")

und das ist mein viewModel

price: ko.computed(function()
{
    return parseFloat(this.replace(' ','').replace(/[^0-9\.]+/g,"")) || '';
},this)

aber dieser Fehler verursacht: Dies hat keine Methode ersetzen ??? Wie kann ich den Preis an die berechnete Funktion übergeben?

19
andrescabana86

Es ist besser, eine benutzerdefinierte Bindung http://knockoutjs.com/documentation/custom-bindings.html zu erstellen, die nur zulässige Zeichen [0-9 ,.] als numerische Darstellung akzeptiert.

setze diese Linie in deine Sicht

<input id="text" type="text" data-bind="numeric, value: number">

fügen Sie diese Linie in Ihr Modell ein (denken Sie daran, die Nummer als beobachtbare Eigenschaft zu binden)

ko.bindingHandlers.numeric = {
    init: function (element, valueAccessor) {
        $(element).on("keydown", function (event) {
            // Allow: backspace, delete, tab, escape, and enter
            if (event.keyCode == 46 || event.keyCode == 8 || event.keyCode == 9 || event.keyCode == 27 || event.keyCode == 13 ||
                // Allow: Ctrl+A
                (event.keyCode == 65 && event.ctrlKey === true) ||
                // Allow: . ,
                (event.keyCode == 188 || event.keyCode == 190 || event.keyCode == 110) ||
                // Allow: home, end, left, right
                (event.keyCode >= 35 && event.keyCode <= 39)) {
                // let it happen, don't do anything
                return;
            }
            else {
                // Ensure that it is a number and stop the keypress
                if (event.shiftKey || (event.keyCode < 48 || event.keyCode > 57) && (event.keyCode < 96 || event.keyCode > 105)) {
                    event.preventDefault();
                }
            }
        });
    }
};
45
Martin Surynek

Knockout hat hierfür Extender. Check This von knockoutjs.com, in dem erläutert wird, wie beobachtbare Extender verwendet werden, um die Eingabe numerisch zu erzwingen. Ich füge den Code aus der Dokumentation hier ein:

Quellcode: Ansicht

<p><input data-bind="value: myNumberOne" /> (round to whole number)</p>
<p><input data-bind="value: myNumberTwo" /> (round to two decimals)</p>

Quellcode: Modell anzeigen

ko.extenders.numeric = function(target, precision) {
    //create a writable computed observable to intercept writes to our observable
    var result = ko.pureComputed({
        read: target,  //always return the original observables value
        write: function(newValue) {
            var current = target(),
                roundingMultiplier = Math.pow(10, precision),
                newValueAsNum = isNaN(newValue) ? 0 : parseFloat(+newValue),
                valueToWrite = Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier;

            //only write if it changed
            if (valueToWrite !== current) {
                target(valueToWrite);
            } else {
                //if the rounded value is the same, but a different value was written, force a notification for the current field
                if (newValue !== current) {
                    target.notifySubscribers(valueToWrite);
                }
            }
        }
    }).extend({ notify: 'always' });

    //initialize with current value to make sure it is rounded appropriately
    result(target());

    //return the new computed observable
    return result;
};

function AppViewModel(one, two) {
    this.myNumberOne = ko.observable(one).extend({ numeric: 0 });
    this.myNumberTwo = ko.observable(two).extend({ numeric: 2 });
}

ko.applyBindings(new AppViewModel(221.2234, 123.4525));
8
Lemo

Ich hatte ein ähnliches Problem.

Ich musste auch nur für Inter-Werte sorgen, und für IE9 und höher (also Typ = Zahl war nicht genug), und da wir viele internationale Kunden haben, konnte ich mich auch nicht auf Schlüsselcodes verlassen. Daher endete das Folgende mit:

//In my js class method (self is this as usual)
self.ensureNumberical = function (data, e) {
    var keyValue = e.key;
    if (keyValue.match(/[0-9]/g)) {
        return true;
    }
    return false;
}

//In my MVC View
data-bind="event: { keypress: ensureNumberical }"
3
Ano nomouis

Ein alternativer Ansatz: Ich habe festgestellt, dass Knockout in Kombination mit jQuery-validate gut funktioniert. Sie müssen lediglich sicherstellen, dass Sie das Formular überprüfen, bevor Sie versuchen, den numerischen Wert zu verwenden.

Angenommen, Sie haben ein Formular-DOM-Element, über das Sie Validierungsregeln einrichten können

$(".yourform").validate({
    rules: {
        year: {
            digits: true,
            minlength: 4,
            maxlength: 4
        }
    },
    messages: {
        year: "Please enter four digits (e.g. 2009).",
    }
});

In Ihrem Ansichtsmodell legen Sie die wechselseitige Bindung wie üblich fest, z. über self.year = ko.observable(""). Stellen Sie nun sicher, dass Sie $(".yourform").valid() aufrufen, bevor Sie self.year() weiter bearbeiten. In meinem Fall mache ich var year = parseInt(self.year(), 10). Gleich nach der Validierung der Formulare wird erwartet, dass dies immer zu einem aussagekräftigen Ergebnis führt.

2

Am besten für das heutige scenerio https://github.com/Knockout-Contrib/Knockout-Validation

führe den Ausschnitt unten aus. Wenn Sie eine andere Ziffer oder etwas mehr als 255 eingeben, wird die Meldung angezeigt.

function model() {
  var self = this;
  this.myObj = ko.observable().extend({ digit: true }).extend({ max: 255});
  }
  
  var mymodel = new model();

$(document).ready(function() {
  ko.validation.init();
  ko.applyBindings(mymodel);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout-validation/2.0.3/knockout.validation.min.js"></script>

enter a digit less than or equal to  255 <input type="text" data-bind="textInput: myObj">

<p>
  Enter something other than a digit or over 255 will cause an error.
</p>

mit freundlicher Genehmigung: Bryan Dellinger: https://stackoverflow.com/a/42940109/3868653

1
xxbinxx
 <input type="text" id="alpha-validation" data-bind="value: YourDataName, valueUpdate: 'afterkeydown' , event: { 'input': AlphaCheck}" style="text-transform:uppercase">

erstellen Sie die AlphaCheck-Funktion und fügen Sie diese hinzu.

    $('#alpha-validation').keyup(function () {
        if (this.value.match(/[^0-9 ]/g)) {
            this.value = this.value.replace(/[^0-9 ]/g, '');
        }
    });

Das wird funktionieren!

1
Hadnazzar

Mit Hilfe des "keydown" -Ereignisses können wir andere Schlüssel im Textfeld einschränken, die numerische Werte enthalten sollen.

$(document).ready(function(){                
        $("selector").on("keydown", function (e) {
            //numbers, delete, backspace, arrows
            var validKeyCodes = [8, 9, 37, 38, 39, 40, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57];
            if (!($.inArray(e.keyCode, validKeyCodes) >= 0))
                    e.preventDefault();                 
        });           
    });
0
Ananth Cool

Erstellen Sie Ihre Datenbindung und zeigen Sie auf Ihren glänzenden neuen Code:

<input id="price" name="price" type="text" data-bind="numeric">

Glänzender neuer Knockout-Code:

price = ko.observable();
price.subscribe(function(newValue) {
    price = newValue.replace(/[\D\.]/g, '');
});

Dies bedeutet, dass jedes Mal, wenn Sie den Preis aktualisieren, die Logik in der Funktion angewendet wird (in diesem Fall müssen Sie alles entfernen, was keine Zahl oder ein Punkt ist) und diese direkt auf den Preis anwenden. Sie können hier auch andere Validierungs- oder Cool-Features hinzufügen, wie z. B. ein Währungssymbol sybmol am Anfang, 2 Dezimalstellen usw.

0
TinyDancer

Wir können den Benutzer auf die Eingabe von Benutzern mit mehr als zwei Dezimalzahlen beschränken. 23.81, 3452.83 Modifizierter Code ist wie folgt. Der Referenzcode stammt aus der Antwort von @Martin Surynek.

HTML -

<p>
    <input data-bind="value: myNumberOne" /> (round to whole number)</p>
  <p>
    <input data-bind="num, value: myNumberTwo" /> (round to two decimals)</p>

Skript -

<script>
    ko.bindingHandlers.num = {
      init: function (element, valueAccessor) {
        $(element).on("keypress", function (event) {
          //debugger
          console.log(event.keyCode);
          var $this = $(this);
          var text = $this.val();

          // Stop insert two dots
          if ($this.val().indexOf('.') != -1 && (event.which == 190 || event.which == 110)) {
            event.preventDefault();
          }

          // Allow: backspace, delete, tab, escape, and enter
          if (event.keyCode == 46 || event.keyCode == 8 || event.keyCode == 9 || event.keyCode == 27 || event.keyCode ==
            13 ||
            // Allow: Ctrl+A
            (event.keyCode == 65 && event.ctrlKey === true) ||
            // Allow: .   ,event.keyCode == 188 ||
            ( event.keyCode == 190 || event.keyCode == 110) ||
            // Allow: home, end, left, right
            (event.keyCode >= 35 && event.keyCode <= 39)) {
            // let it happen, don't do anything
            return;
          }

          // Ensure that it is a number and stop the keypress
          if (event.shiftKey || (event.keyCode < 48 || event.keyCode > 57) && (event.keyCode < 96 || event.keyCode >
              105)) {
            event.preventDefault();
          }

          if ((event.which == 46) && (text.indexOf('.') == -1)) {
            setTimeout(function () {
              if ($this.val().substring($this.val().indexOf('.')).length > 3) {
                $this.val($this.val().substring(0, $this.val().indexOf('.') + 3));
              }
            }, 1);
          }

          if ((text.indexOf('.') != -1) &&
            (text.substring(text.indexOf('.')).length > 2) &&
            (event.which != 0 && event.which != 8) &&
            ($(this)[0].selectionStart >= text.length - 2)) {
            event.preventDefault();
          }          
          //console.log($(this)[0].selectionStart >= text.length - 2);
        });
      }
    };


    ko.extenders.numeric = function (target, precision) {
      //create a writable computed observable to intercept writes to our observable

      var result = ko.pureComputed({
        read: target, //always return the original observables value
        write: function (newValue) {

          var current = target(),
            roundingMultiplier = Math.pow(10, precision),
            newValueAsNum = isNaN(newValue) ? 0 : parseFloat(+newValue),
            valueToWrite = Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier;

          //only write if it changed
          if (valueToWrite !== current) {
            target(valueToWrite);
          } else {
            //if the rounded value is the same, but a different value was written, force a notification for the current field
            if (newValue !== current) {
              target.notifySubscribers(valueToWrite);
            }
          }
        }
      }).extend({
        notify: 'always'
      });

      //initialize with current value to make sure it is rounded appropriately
      result(target());

      //return the new computed observable
      return result;
    };

    function AppViewModel(one, two) {
      this.myNumberOne = ko.observable(one).extend({
        numeric: 0
      });
      this.myNumberTwo = ko.observable(two).extend({
        numeric: 2
      });
    }

    ko.applyBindings(new AppViewModel(221.2234, 123.4525));
  </script>
0

Ich weiß, dass diese Frage ein Jahr alt ist, aber lassen Sie mich dies für den Feature-Besucher der Seite posten.

Überprüfen Sie dies heraus:

ko.bindingHandlers.numericnumbers = {
init: function (element) {
    $(element).on('keypress', function (number) {
        number = (number) ? number : window.event;
        var charcode = (number.which) ? number.which : number.keyCode;
        if (charcode > 31 && (charcode < 48 || charcode > 75))
            number.preventDefault();
    });
}};
0
Jed Monsanto