Ich erstelle eine Benutzeroberfläche für Berechtigungen. Ich habe eine Liste mit Berechtigungen mit einer Auswahlliste neben jeder Berechtigung. Die Berechtigungen werden durch ein beobachtbares Array von Objekten dargestellt, die an eine Auswahlliste gebunden sind:
<div data-bind="foreach: permissions">
<div class="permission_row">
<span data-bind="text: name"></span>
<select data-bind="value: level, event:{ change: $parent.permissionChanged}">
<option value="0"></option>
<option value="1">R</option>
<option value="2">RW</option>
</select>
</div>
</div>
Das Problem ist nun folgendes: Das Änderungsereignis wird ausgelöst, wenn die Benutzeroberfläche zum ersten Mal gefüllt wird. Ich rufe meine Ajax-Funktion auf, erhalte die Berechtigungsliste und dann wird das Ereignis für jedes der Berechtigungselemente ausgelöst. Das ist wirklich nicht das Verhalten, das ich will. Ich möchte, dass es nur ausgelöst wird, wenn ein Benutzer wirklich einen neuen Wert für die Berechtigung in der Auswahlliste auswählt . Wie kann ich das tun?
quelle
select
Element getestet . Selbst wenn der Anfangswert der Auswahl mit einer der Optionen übereinstimmte, wurde daschange
Ereignis dennoch ausgelöst . Als ich diesen einfachenif
Block im Handler implementiert habe , hat alles wie erwartet funktioniert. Versuchen Sie zuerst diese Methode. Danke, @Sarath!Dies ist nur eine Vermutung, aber ich denke, es passiert, weil
level
es eine Zahl ist. In diesem Fallvalue
löst die Bindung einchange
Ereignis aus, daslevel
mit dem Zeichenfolgenwert aktualisiert werden soll. Sie können dies daher beheben, indem Sie sicherstellen, dasslevel
es sich um eine Zeichenfolge handelt.Darüber hinaus besteht die "Knockout" -Methode darin, keine Ereignishandler zu verwenden, sondern Observables und Abonnements zu verwenden. Machen Sie
level
ein Observable und fügen Sie ihm ein Abonnement hinzu, das bei jederlevel
Änderung ausgeführt wird.quelle
Hier ist eine Lösung, die bei diesem seltsamen Verhalten helfen kann. Ich konnte keine bessere Lösung finden, als eine Schaltfläche zum manuellen Auslösen des Änderungsereignisses zu platzieren.
EDIT: Vielleicht könnte eine benutzerdefinierte Bindung wie diese helfen:
Und fügen Sie in Ihrem ausgewählten Datenbindungsattribut Folgendes hinzu:
quelle
Ich benutze diese benutzerdefinierte Bindung (basierend auf dieser Geige von RP Niemeyer, siehe seine Antwort auf darauf Frage), die sicherstellt, dass der numerische Wert ordnungsgemäß von Zeichenfolge in Zahl konvertiert wird (wie von der Lösung von Michael Best vorgeschlagen):
Javascript:
Beispiel HTML:
quelle
Wenn Sie einen beobachtbaren Wert anstelle eines primitiven Werts verwenden, löst die Auswahl beim ersten Binden keine Änderungsereignisse aus. Sie können weiterhin an das Änderungsereignis binden, anstatt das Observable direkt zu abonnieren.
quelle
Schnell und schmutzig mit einer einfachen Flagge:
Wenn dies nicht funktioniert, versuchen Sie, die letzte Zeile in ein setTimeout () zu verpacken. Ereignisse sind asynchron. Möglicherweise steht das letzte noch aus, wenn applyBindings () bereits zurückgegeben wurde.
quelle
Ich hatte ein ähnliches Problem und habe gerade den Ereignishandler geändert, um den Typ der Variablen zu überprüfen. Der Typ wird erst festgelegt, nachdem der Benutzer einen Wert ausgewählt hat, nicht beim ersten Laden der Seite.
Das scheint bei mir zu funktionieren.
quelle
benutze das:
quelle
Probier diese:
quelle
Wenn Sie mit Knockout arbeiten, verwenden Sie die Schlüsselfunktionalität von Knockout für beobachtbare Funktionen.
Verwenden Sie die
ko.computed()
Methode und führen Sie innerhalb dieser Funktion einen Ajax-Aufruf aus.quelle