25 votos

KnockoutJS suscribirse a los cambios de la propiedad con la Asignación de Plugin

Existe de todos modos me puede decir a los octavos de final de asignación de plugin para suscribirse a todos los cambios de propiedad que se llame a una función determinada?

Me doy cuenta de que puedo manualmente suscribirse al evento de cambio de propiedad de esta manera:

var viewModel = {
    name: ko.observable('foo'),
}

// subscribe manually here
viewModel.name.subscribe(function(newValue){
   // do work
})

Me gustaría ser capaz genéricamente suscribirse a pesar de que, desde mi punto de vista de los modelos pueden variar, no quiero codificar los nombres de las propiedades. He creado una función que hace esto, pero no puede ser el mejor enfoque. Funciona a través de todos los navegadores excepto internet explorer 7 y siguientes.

Aquí me tomo un viewmodel como un argumento y tratar de reflejar en él la suscripción a las propiedades:

function subscribeToKO(data) {

        $.each(data, function (property, value) {
            if (getType(value) == "Object")
                data[property] = subscribeToKO(value);
            else if (getType(value) == "Array") {
                $.each(value, function (index, item) {
                    item = subscribeToKO(item);
                });
            }
            else {
                if (value.subscribe) {
                    value.subscribe(function (newValue) {
                        // do work                                         
                    });
                }
            }
        });
        return data;
    }

Como he dicho esto funciona, pero desde que estoy usando el mapeo de pluging tenía la esperanza de que allí había un gancho que podría utilizar para proporcionar una función que genéricamente suscribirse a los cambios de propiedad.

Algo así como:

mapping = {
   create: function(options){
       options.data.subscribe(function(newValue){
            // do work ???
       });
   }
}

ko.mapping.fromJS(viewModel, mapping);

Alguna idea?

9voto

Matthew Kelly Puntos 1131

He aquí un enfoque genérico basado en Ryan Niemeyer sucia bandera.
Haga clic aquí para la JsFiddle.

Html:

<ol>
<li>
    Telephone : <input data-bind="value: telephone"/>
</li>
<li>
    Address : <input data-bind="value: address"/>
</li>
</ol>​

Javascript:

var model = {
    telephone: ko.observable('0294658963'),
    address: ko.observable('167 New Crest Rd')

};
// knockout extension for creating a changed flag (similar to Ryan's dirty flag except it resets itself after every change)
ko.changedFlag = function(root) {
    var result = function() {};
    var initialState = ko.observable(ko.toJSON(root));

    result.isChanged = ko.dependentObservable(function() {
        var changed = initialState() !== ko.toJSON(root);
        if (changed) result.reset();
        return changed;
    });

    result.reset = function() {
        initialState(ko.toJSON(root));
    };

    return result;
};
// add changed flag property to the model
model.changedFlag = new ko.changedFlag(model);
// subscribe to changes
model.changedFlag.isChanged.subscribe(function(isChanged) {
    if (isChanged)  alert("model changed");
});
ko.applyBindings(model);​

3voto

Ziad Puntos 460

Este pequeño y práctico plugin es bastante cerca de lo que hicimos, pero viene con varias opciones y pueden funcionar a través de un conjunto mucho más amplio de requisitos sin necesidad de que la Asignación de plugin:

https://github.com/ZiadJ/knockoutjs-reactor

Básicamente permite escribir este tipo de código:

ko.watch(viewModel, function(target, trigger) { 
    // do work
});  

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X