Come usare attacchi personalizzati?
-
14-10-2019 - |
Domanda
Ho una grande ViewModel, e vorrei inviare l'aggiornamento di uno status ( "leggere" / "non letto") al server senza inviare l'intero modello.
Quello che ho fatto è creare un personalizzato Binding in questo modo:
ko.bindingHandlers.statusUpdater = {
update: function(element, valueAccessor) {
console.log(element);
}
};
Nel modello:
<div data-bind='template: { name: "contactsListTemplate", data: viewModel.conversations.conversationlist }'> </div>
<script type="text/html" id="contactsListTemplate">
<table>
<tbody>
{{each(i, conversation) $data}}
<tr>
<td>
<input type="checkbox" data-bind="checked: read, statusUpdater: conversation_id" />
</td>
</tr>
{{/each}}
</tbody>
</table>
</script>
Per la rilegatura l'usanza, mi interessa solo in Aggiornamenti, quello che ho pensato che mi avrebbe permesso di fare è rilevare un aggiornamento con KnockoutJS, e determinare quale elemento è stato aggiornato in modo da poter afferrare che gli elementi ID, e le nuove statistiche, e poi inviare che al server.
Quello che sta succedendo è la la customBinding è console.log
ging ogni singola casella di controllo su una singola modifica casella di controllo. Questo significa che cambiare una casella di controllo e tutte e 3 le caselle di controllo accedono alla console tramite il ko.bindingHandlers.statusUpdater
.
ho pensato di aggiungere un evento click al data-binding, ma che non sembrava pulito come vincolante un costume. Forse quello che sto cercando di fare con attacchi personalizzati non è quello che stanno per?
Pensieri?
Soluzione
La ragione per il suo fare che è perché il metodo di aggiornamento viene chiamato ogni momento il valore del modello viene aggiornato e alla partenza dopo il metodo init viene chiamato.
Il metodo di rilegatura di aggiornamento è per voi di impostare lo stato dell'elemento DOM bound quando cambia ViewModel.
Se si desidera reagire ad un cambiamento e aggiornare il ViewModel sarà necessario implementare il metodo init e collegare un evento (click, modificare ecc) In questo gestore è quindi possibile inviare l'aggiornamento di stato al vostro ViewModel.
ko.bindingHandlers.statusUpdater = {
'init': function (element, valueAccessor, allBindingsAccessor) {
var updateHandler = function() {
var valueToWrite;
if (element.type == "checkbox") {
valueToWrite = element.checked;
} else if ((element.type == "radio") && (element.checked)) {
valueToWrite = element.value;
} else {
return; // "checked" binding only responds to checkboxes and selected radio buttons
}
var modelValue = valueAccessor();
if (ko.isWriteableObservable(modelValue)) {
if (modelValue() !== valueToWrite) { // Suppress repeated events when there's nothing new to notify (some browsers raise them)
$.ajax({
url: 'someurl',
success: function(data) {
alert('status update');
}
});
modelValue(valueToWrite);
}
} else {
var allBindings = allBindingsAccessor();
if (allBindings['_ko_property_writers'] && allBindings['_ko_property_writers']['checked']) {
allBindings['_ko_property_writers']['checked'](valueToWrite);
}
}
};
$(element).click(updateHandler).change(updateHandler);
},
'update': function (element, valueAccessor) {
ko.bindingHandlers.checked(element, valueAccessor);
}
};
Il modo migliore per imparare questo che ho trovato è stato quello di guardare la versione di debug di KO su git. Quello che si vuole raggiungere è fondamentalmente una versione modificata controllato vincolante con una chiamata AJAX.
Non ho provato la sopra ma dovrebbe iniziare.
Saluti,
Ian