2016-06-04 10 views
0

Ich frage mich, ob es einen Grund gibt, einen Prototyp Funktion/ViewModel-Funktion gegenüber dem anderen vorzuziehen.JavaScript - Prototyp-Funktion vs. ViewModel-Funktion?

Sagen Sie bitte eine ganze Zahl 1234 als Geldwert wie 12.34€

darstellen wollte, was ich tat, war, erstellen Sie eine Prototyp-Funktion auf dem Number Objekt:

Number.localeSeparator = 1.1.toLocaleString().substr(1, 1); 

Number.prototype.centToEuro = function (separator_string) { 
    if (!separator_string) { 
     separator_string = Number.localeSeparator; 
    } 
    return (this/100).toFixed(2).replace(".", separator_string) + "€"; 
} 

var vm = {myMoney: ko.observable(1234)}; 
ko.applyBindings(vm); 

Diese Daten verbindlich ziemlich einfach , weil alles, was ich in der Ansicht tun musste, dies war:

<div data-bind="text: myMoney().centToEuro()"></div> 

Aber anstelle eines Prototyps functio n, ich könnte auch eine Ansichtsmodell Funktion mit fast dem gleichen Code erstellen, etwa so:

var vm = { 
    myMoney: ko.observable(1234), 
    localeSeparator: 1.1.toLocaleString().substr(1, 1), 
    centToEuro: function (value_int, separator_string) { 
     if (!separator_string) { 
      separator_string = vm.localeSeparator; 
     } 
     return (value_int/100).toFixed(2).replace(".", separator_string) + "€"; 
    } 
} 
ko.applyBindings(vm); 

in der Ansicht gebraucht, würde es so aussehen:

<div data-bind="text: centToEuro(myMoney())"></div> 

Wie Sie sagen, die beide HTML-Zeilen sind fast genau gleich lang und unterscheiden sich nur im Ansatz. Die Frage ist also, welcher Ansatz vorzuziehen ist?

Antwort

3

Vorausgesetzt, dass centToEuro nichts mit willkürlichen Zahlen zu tun hat, aber mit dem bestimmten Modell für Geld, mit dem Sie hier zu tun haben, und dass Sie die eingebauten Prototyp-Objekte nicht erweitern sollten, gehen Sie für die Viewmodel-Funktion.

+0

Okay, macht Sinn. Und wenn jemand benutzerdefinierte Funktionen für beliebige Zahlen verwenden wollte? Kann dazu eine generelle Aussage getroffen werden oder hängt es vom Anwendungsfall ab, ob der Prototyp erweitert werden soll oder nicht? – jaySon

+0

In diesem Fall wird es immer noch als eine [schlechte Idee] (http://stackoverflow.com/q/10197174/1048572) betrachtet (siehe auch die Links in den Kommentaren dort). – Bergi

1

Ist nicht die Bedeutung Ihrer Frage, wo diese Art Funktion zu setzen?

Verwenden Sie Extender, für Aufgaben wie Währungsformatierung und so weiter, wo Sie einmal einrichten und überall verwenden. Nur ein Beispiel:

ko.extenders.currency = function (target, option) { 
    target.amount = function() { 
     var amt = ko.unwrap(target); 
     var localeSeparator = 1.1.toLocaleString().substr(1, 1); 
     switch(option) { 
      case "Eur": 
       amt = (amt/100).toFixed(2).replace(".", localeSeparator) + "€"; 
       break; 
      default:; 
      } 
     return amt; 
    }; 
    return target; 
}; 

Ansicht Modell:

myMoney: ko.observable("1234").extend({currency: "Eur"}) 

Markup:

<div data-bind="text: myMoney.amount()"></div> 
+0

Diese Antwort ist tatsächlich sehr hilfreich für dieses spezielle Problem, Daumen hoch für das. Aber meine Frage war wirklich, was als eine bessere Praxis angesehen wird, z.B. für Hilfsfunktionen (wie in diesem Fall). Unabhängig vom MVVM-Muster (und Knockout) weiß ich einfach nicht, warum ich einen Ansatz dem anderen vorziehen sollte, denn keiner scheint Leistung, Platz, Stabilität oder so etwas zu kosten. – jaySon