Ich habe eine Reihe von Artikeln, die vom Dienst zurückkommen. Ich versuche, ein berechnetes Observable für jede Item-Instanz zu definieren, also sagt mein Instinkt, dass ich es auf den Prototyp setzen soll.Sind in KnockoutJS berechnete Observablen für Prototypen realisierbar?
Ein Fall für das berechnete Observable: Das System berechnet Punkte, aber der Benutzer kann den berechneten Wert überschreiben. Ich muss den berechneten Wert verfügbar halten, falls der Benutzer die Überschreibung entfernt. Ich muss auch benutzerdefinierte und berechnete Punkte zusammenführen und die Summen addieren.
I-Mapping bin mit der folgenden Funktionen ausführen:
var itemsViewModel;
var items = [
{ 'PointsCalculated' : 5.1 },
{ 'PointsCalculated' : 2.37, 'PointsFromUser' : 3 }
];
var mapping = {
'Items' : {
create : function(options) {
return new Item(options.data);
}
}
};
var Item = function(data) {
var item = this;
ko.mapping.fromJS(data, mapping, item);
};
Item.prototype.Points = function() {
var item = this;
return ko.computed(function() {
// PointsFromUser may be 0, so only ignore it if the value is undefined/null
return (item.PointsFromUser != null) ? item.PointsFromUser : item.PointsCalculated;
});
};
ko.mapping.fromJS(items, mapping, itemsViewModel);
So wie es jetzt funktioniert, ich habe die anonyme Funktion aufrufen, die berechnete beobachtbaren zurückzukehren. Das scheint für jede Bindung eine neue Instanz der berechneten Observablen zu schaffen, die den größten Teil des Punktes, an dem sie auf den Prototyp gesetzt wird, zunichte macht. Und es ist ein wenig lästig, zu entziffern, wie viele Klammern jedesmal benutzt werden müssen, wenn ich auf ein Observable zugreife.
Es ist auch etwas zerbrechlich. Wenn ich Punkte für den Zugriff() im Code versuche, kann ich nicht
var points = 0;
var p = item.Points;
if (p && typeof p === 'function') {
points += p();
}
, weil das zu Kontext der Punkte ändert(), um DOMWindow, statt Artikel.
Wenn ich die berechnete in create() in das Mapping, konnte ich den Kontext erfassen, aber dann gibt es eine Kopie der Methode für jede Objektinstanz.
Ich habe Michael Bests Google Groups Post gefunden (http://groups.google.com/group/knockoutjs/browse_thread/thread/8de9013fb7635b13). Der Prototyp gibt ein neues berechnetes Observable auf "activate" zurück. Ich habe nicht herausgefunden, was "aktivieren" (vielleicht Objs?) Genannt wird, aber ich vermute, dass es immer noch einmal pro Objekt passiert, und ich habe keine Ahnung, welchen Umfang "dieses" bekommen wird.
An diesem Punkt glaube ich, dass ich nicht mehr in den veröffentlichten Dokumenten bin, aber ich arbeite immer noch daran, zu entschlüsseln, was von der Quelle geschieht.
Danke. Ich denke, dass der Zweck von .Extend() gerade geklickt hat. Dies löst meine Scoping/Doppelfunktion Aufrufprobleme schön, und ich werde dein Wort nehmen, dass Knockout mich nicht das tatsächlich errechnete Observable auf dem Prototyp behalten lässt. –
Eric, könnten Sie eine mehr "Zucker" Version zur Verfügung stellen? So etwas wie childClass = BaseClass.extend (function() {/*...*/}), das bereits die Konfiguration der Prototypkette durchführt? Es manuell für jede Klasseninstanz zu tun ist ein bisschen seltsam ... – fbuchinger
Ich sehe keinen Grund, warum Sie nicht eine statische Funktion 'erweitern' auf den geerbten Konstruktor setzen könnte, solange es im Grunde genommen: ' SubClass.extend = Funktion (Extender) {SubClass.prototype.extend (Extender); }; ' – ericb