web-dev-qa-db-fra.com

Knockout.JS: déclencheurs basés sur des changements dans un observable

J'ai un élément d'entrée qui est lié à un knockout observable:

<input type="text" data-bind="value: myText, valueUpdate: 'keyup'" />

Cela met à jour l'observable sur chaque touche. Je veux maintenant déclencher des événements supplémentaires lorsque la valeur change.

Ce qui suit fait cela en principe:

this.myTextTrigger = ko.computed( function () {
    console.log( this.myText() );
}, this );

Cependant, cela semble quelque peu maladroit. Il se déclenche également lors de l'instanciation initiale du modèle, où je souhaite uniquement gérer les modifications après cela. Existe-t-il un moyen officiel/plus simple de déclencher des événements en fonction des modifications des observables?

24
gzost

Utilisez abonnez-vous:

this.myText.subscribe(function (newText) {
   console.log(newText);
});

Si vous souhaitez réutiliser ce déclencheur, vous pouvez envisager d'écrire une liaison personnalisée .

44
meze

Si vous essayez d'obtenir des informations supplémentaires dans votre liaison, utilisez allBindings.get(nameOfOtherBinding) et définissez le paramètre nameOfOtherBinding pour faire référence au nom de la liaison dans cet élément qui pointe vers une fonction. Soit mettez la fonction littérale dans le code HTML, soit assurez-vous que vous pouvez trouver cette fonction dans la portée de la définition des gestionnaires (comme attachée globalement à l'objet window).

http://knockoutjs.com/documentation/custom-bindings.html

JS Fiddle Example - http://jsfiddle.net/pqb4xubg/

Le javascript qui configurerait le gestionnaire (soit dans init ou update):

ko.bindingHandlers.generic = {
    init: function(element, valueAccessor, allBindings){
        var val = 'nothing';
        // set your other bindings to get pulled in
        var func = allBindings.get('func');
        // normal check if the binding is actually a function
        if(typeof func === 'function'){
            // use the retrieved function
            val = func(valueAccessor());
        }
        element.innerText = val;
    }
};
var model = {a:'4', b:5};
ko.applyBindings(model);

Le html qui utiliserait le gestionnaire (remarquez comment les éléments avec la liaison "fun" ne fonctionnent pas):

<div data-bind="generic: a, func: function( val ){ return val + 2; }"></div>
<div data-bind="generic: a, fun: function( val ){ return val + 2; }"></div>
<div data-bind="text: a"></div>
<div data-bind="generic: b, func: function( val ){ return val + 2; }"></div>
<div data-bind="generic: b, fun: function( val ){ return val + 2; }"></div>
<div data-bind="text: b"></div>

Vous pouvez également simplement utiliser l'initialisation de la liaison pour configurer les gestionnaires d'événements DOM standard et appeler simplement ces fonctions explicitement en utilisant quelque chose comme jQuery. Je vous remercie. Bonne journée.

3
Yemi Bedu