0

Ich habe ein Formular mit Datensätzen. Wenn ich auf ein Set (oder eine Zeile) klicke, füllt es das Formular mit diesem Datensatz.Knockout PureComputed Aufrufen von Abonnenten beim Erstellen

Für jedes Set habe ich ein pureComputed-Objekt, das die Datenbank aktualisiert, wenn sich einer der Eingänge ändert.

Das funktioniert gut, außer dass pureComputed das Update aufruft, wenn ich auf ein anderes Set klicke. Ich erwarte, dass dies nicht passiert, weil ich die Menge der Eingaben mit einem Konstruktor erstelle und so im Wesentlichen alle Observablen und ihre jeweilige pureComputed-Eigenschaft ersetze.

Zum Beispiel:

var Form = function (data) { 
    var $this = this; 
    $this.value1 = ko.observable(data.value1); 
    $this.value2 = ko.observable(data.value2); 
    $this.model = ko.pureComputed(function() { 
     return { 
      value1: $this.value1(), 
      value2: $this.value2(), 
     }; 
    }).extend({ updateModel: url }); 
}; 

//Inside some module 
var self = this; 
self.viewmodel = {}; 

var load = function (url) { 
    $.ajax({ 
     url: url, //etc 
    }).done(function (response) { 
     self.viewmodel.form(new Form(response)); 
    }); 
}; 
load('www.myapi.com/1'); 

var onClick = function() { 
    load('www.myapi.com/2'); 
}; 

Auch wird das Update nicht beim Laden der Seite aufgerufen. Warum wird es aufgerufen, wenn ich auf eine neue Zeile klicke?

EDIT: Update Code ...

ko.extenders.updateModel = function (target, options) { 
    var url = options; 

    target.subscribe(function (model) { 
     $.ajax({ 
      url: url, 
     }).done(function (response) { 
      /* not setting any observables */ 
     }); 
    }; 

    return target; 
}; 

EDIT 2: Die oben in meinem Code tatsächlich funktioniert. Ich habe den Schuldigen auf die Knockout-Bindungen für das Dropdown reduziert.

Teil jedes Formulars ist ein Dropdown. Ich benutze Knockouts eingebaute Bindings für das Dropdown und schließe einen Platzhalter ein. Wenn der Wert des Dropdown-Menüs null oder 0 ist, ruft der Wert die Subcriptions auf. Wenn es größer als 0 ist, ist es in Ordnung.

+0

Können Sie zeigen, was 'updateModel' tut? –

Antwort

1

Ich habe Ihren Code genommen und hier eine funktionierende Beispielversion erstellt. Die Aktualisierungsfunktion wird nur ausgeführt, wenn die Werte geändert werden. Mit anderen Worten, der "Klick" aktualisiert nichts.

ko.extenders.updateModel = function (target, options) { 
 
    var url = options; 
 

 
    target.subscribe(function (foo) { 
 
    console.log(url, foo); 
 
    }); 
 

 
    return target; 
 
}; 
 

 
var Form = function (data) { 
 
    var $this = this; 
 
    $this.value1 = ko.observable(data.value1); 
 
    $this.value2 = ko.observable(data.value2); 
 
    $this.model = ko.pureComputed(function() { 
 
    return { 
 
     value1: $this.value1(), 
 
     value2: $this.value2(), 
 
    }; 
 
    }).extend({ updateModel: data.url }); 
 
}; 
 

 
//Inside some module 
 
var vm = {}; 
 
vm.viewmodel = { 
 
    form: ko.observable() 
 
}; 
 

 
var counter = 0; 
 
var load = function (url) { 
 
    url = url + (++counter); 
 
    setTimeout(function() { 
 
    vm.viewmodel.form(new Form({ 
 
     value1: "1"+counter, 
 
     value2: "2"+counter, 
 
     url: url 
 
    })); 
 
    }, 100); 
 
}; 
 

 
load('www.myapi.com/'); 
 

 
vm.onClick = function() { 
 
    load('www.myapi.com/'); 
 
}; 
 

 
ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script> 
 
<div data-bind="with: viewmodel.form"> 
 
    <input data-bind="value: value1"> 
 
    <input data-bind="value: value2"> 
 
</div> 
 
<button type="button" data-bind="click: onClick">click</button>

+0

Das ist großartig! Es ist, was ich mache, aber ich bekomme immer Updates. Meine reale Lösung verwendet Kendo-Raster, um ein Raster zu füllen, und wenn Sie auf die Zeilen klicken, wird das Formular ausgefüllt. Ich denke, ich muss nur den ganzen Code durchkämmen (wieder) und sicherstellen, dass ich nichts mache, was ein Abonnement auslösen würde. :/ – christo8989

+0

Ich habe das Problem entdeckt. Es ist nicht damit verbunden. Es hat mehr mit Knockout-Bindungen für Optionen mit einem Platzhalter zu tun. Anywho, sollte ich diese Frage löschen? – christo8989

+0

Ich habe es herausgefunden. Ich initialisierte den Dropdown-Wert auf null statt auf undefiniert und so änderte sich der Wert tatsächlich von Null zu undefiniert. – christo8989

Verwandte Themen