Estoy teniendo un problema con el knock-out «checked» de unión. Parece que el evento «change» en la casilla de verificación de retorno valor antiguo, antes de que se actualiza(de forma que si se fue sin marcar devolverá false). No creo que me pueden suscribirse al valor ya que lo tengo en el interior del objeto.

<tbody data-bind="foreach: Categories">
                <tr>
                    <td><input type="checkbox" data-bind="checked: ShowOpened, event: { change: $root.CategoryChange }" /></td>
                </tr>
            </tbody>
<script type="text/javascript">
var Category = function (Id, Name, Order, ShowOpened) {
    this.Id = Id;
    this.Name = Name;
    this.Order = Order;
    this.ShowOpened = ShowOpened;
    this.IsUpdated = ko.observable(false);

    this.OldOrder = Order;
    this.OldShowOpened = ShowOpened;
};
var ViewModel = {
    Categories: ko.observableArray([]),
    CategoryChange: function(pCategory) {
        if(pCategory.Order != pCategory.OldOrder || pCategory.ShowOpened != pCategory.OldShowOpened)
            pCategory.IsUpdated(true);
        else
            pCategory.IsUpdated(false);
    }
};
ko.applyBindings(ViewModel);
</script>

Por lo que en este ejemplo he ShowOpened casilla de verificación que puede desencadenar CategoryChange método que va a cambiar una variable dentro del objeto(que necesito más tarde para saber de qué objeto se actualizan). Pero cuando el chechbox se cambia siempre enviar el valor antiguo método de disparo y, a continuación, cambie el valor. Hay alguna forma de arreglar esto?

  • Algo está mal con tu código. Ni ShowOpened ni IsUpdated están ko.observables (y probablemente es por eso que siempre se obtiene el valor antiguo). ¿Cómo puede este código, aun de trabajo? CategoryChange debe lanzar una excepción.
  • estás wright, he cometido un error a la hora de crear este post originalmente. Pero aún así el error señalado no es el problema.
  • Oi, todavía falta este: this.ShowOpened = ko.observable(ShowOpened); y este: pCategory.ShowOpened(). Debo decir, que hemos hecho un montón de errores al escribir este post…
InformationsquelleAutor akhabaiev | 2012-07-02

3 Comentarios

  1. 62

    Desde que se conservan en el que indica que la falta de ko.observables no es un problema, he mirado más de cerca. Parece que estás en lo correcto! El change evento es disparado antes de el valor real es un conjunto. Me temo que no sé la razón de esto.

    Pero hay una forma fácil de solucionar este problema: acaba de cambiar change evento click evento:

    <input type="checkbox" data-bind="checked: ShowOpened, click: $root.CategoryChange" />

    Recuerde que usted tiene que poner explícitamente return true; al final de click controlador de eventos. De lo contrario, el nuevo valor no se establece en la casilla de verificación.

    Si usted no desea utilizar click evento, puedes hacerlo de la otra manera. Suscribirse a los cambios de ShowOpened:

    this.ShowOpened = ko.observable(ShowOpened);
    this.ShowOpened.subscribe(function(newValue) {
        /* Do something when ShowOpened changes.
           newValue variable holds the new value, obviously. :) */
    });
    • Gran, evento click obras. He probado begore, simplemente se olvidó de devolver true, y la casilla de verificación nunca tengo activada/desactivada. Gracias.
    • Yo tenía exactamente el mismo problema con IE no reconoce la change evento. Grr.
    • Funciona perfecto! Gracias. El «return true;» es la clave para que esto funcione correctamente!
    • Wow esto funciona, parece un error en el cambio: evento en octavos de final a mí…
    • Es bueno que el evento click se activa incluso cuando yo presione la barra espaciadora y la casilla de verificación tiene el foco.
    • Yo estaba usando dos casillas de verificación antes de leer esta respuesta, ya que no se devuelve true. Gracias por la buena solución.
    • Me había olvidado .suscribirse(func). Me gusta ese enfoque bastante.

  2. 6

    Trate de usar subscribe en lugar de enlace de evento. Esto debería funcionar ahora

    <table>
        <tbody data-bind="foreach: Categories">
            <tr>
                <td><input type="checkbox" data-bind="checked: ShowOpened" /></td>
            </tr>
        </tbody>
    <table>
    
    var Category = function (Id, Name, Order, ShowOpened) {
        this.Id = Id;
        this.Name = Name;
        this.Order = Order;
        this.ShowOpened = ko.observable(ShowOpened);
        this.IsUpdated = false;
    
        this.OldOrder = Order;
        this.OldShowOpened = ShowOpened;
    
        this.ShowOpened.subscribe(function (newShowOpened) {
            if(this.Order != this.OldOrder || this.ShowOpened() != this.OldShowOpened)
                this.IsUpdated = true;
            else
                this.IsUpdated = false;
        }, this);
    };
    var ViewModel = {
        Categories: ko.observableArray([])
    };
    ko.applyBindings(ViewModel);

    O como alternativa (y en mi opinión, la mejor solución) puede utilizar dependentObservable, que ahora se llama computed. He aquí como se vería

    <table>
        <tbody data-bind="foreach: Categories">
            <tr>
                <td>
                    <input type="checkbox" data-bind="checked: ShowOpened" />
                    <span data-bind="text: IsUpdated"></span>
                </td>
            </tr>
        </tbody>
    </table>
    var Category = function (Id, Name, Order, ShowOpened) {
        this.Id = Id;
        this.Name = Name;
        this.Order = Order;
        this.ShowOpened = ko.observable(ShowOpened);
        this.OldOrder = Order;
        this.OldShowOpened = ShowOpened;
        this.IsUpdated = ko.computed(function () {
            return this.Order != this.OldOrder || this.ShowOpened() != this.OldShowOpened;
        }, this);
    };
    var ViewModel = {
        Categories: ko.observableArray([])
    };
    ko.applyBindings(ViewModel);
  3. 0

    También he tenido este problema, pero yo no podía usar suscribirse solución, porque yo ya estaba suscrito a el mismo campo con una petición ajax que podría restablecer el valor. El código, a continuación, permanecer en un bucle cuando la ha cambiado. Así que he añadido la siguiente solución (su feo pero funciona).

    $("input[type='radio'], input[type='checkbox']", element).on("change", function (e, data) {
        setTimeout(function () {
            $(this).trigger("afterChange", data);
        }.bind(this), 10);
    }); 

    A continuación, en lugar de escuchar a los cambio me gustaría escuchar el afterChange evento.

    <div data-bind="foreach: answerList">
        <input type="checkbox" data-bind="event: { afterChange: $root.sendSelectedAnswer($data) }"/>
    </div>

    Sé que no es la mejor solución, pero en mi caso yo no tenía ninguna otra opción.

Dejar respuesta

Please enter your comment!
Please enter your name here