Pregunta

Tengo un gran modelo de vista, y me gustaría publicar la actualización de un estado ( "leer" / "sin leer") al servidor sin publicar todo el modelo.

Lo que he hecho es crear un enlace personalizado de este modo:

ko.bindingHandlers.statusUpdater = {
    update: function(element, valueAccessor) {
        console.log(element);
    }
};

En la plantilla:

<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>

Para la unión la costumbre, sólo estoy interesado en las actualizaciones, lo que pensé que me permitiría hacer es detectar una actualización con KnockoutJS, y determinar qué elemento se actualiza para que pudiera agarrar que los artículos Identificación y nuevas estadísticas, y luego puesto que al servidor.

Lo que está pasando es la del customBinding se console.logging cada casilla solo en una sola modificación casilla. Esto significa que el cambio de una casilla de verificación y los 3 casillas de verificación están conectando a la consola a través de la ko.bindingHandlers.statusUpdater.

I pensado en añadir un evento de clic al enlace de datos, pero que no parecía tan limpio como sea vinculante una costumbre. Tal vez lo que estoy tratando de hacer con los enlaces personalizados no es para qué son?

Los pensamientos?

¿Fue útil?

Solución

La razón de su hacer eso se debe a que el método de actualización se llama cada vez que se actualiza el valor del modelo y en el inicio después de que se llama al método init.

El método de encuadernación actualización es para establecer el estado del elemento dom obligado cuando los cambios ViewModel.

Si desea reaccionar a un cambio y actualizar el modelo de vista que tendrá que poner en práctica el método init y adjuntar un evento (clic, cambiar, etc.) En este controlador se puede enviar la actualización de estado a su modelo de vista.

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);
    }
};

La mejor manera de aprender esto que encontré fue a mirar la versión de depuración de KO en git. Lo que se quiere lograr es básicamente una versión modificada comprobado unión con una llamada AJAX.

No he probado lo anterior sino que debe empezar.

Saludos,

Ian

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top